Smooth scroll does not work in ViewPager (support library)

11,337

I've fixed this by creating a MyViewPager that overrides the ViewPager.mScroller using reflection.

public class MyViewPager extends ViewPager 
{
  public MyViewPager( Context context, AttributeSet attrs) 
  {
    super( context, attrs );
    setMyScroller();
  }
  private void setMyScroller() 
  {
    try 
    {
            Class<?> viewpager = ViewPager.class;
            Field scroller = viewpager.getDeclaredField("mScroller");
            scroller.setAccessible(true);
            scroller.set(this, new MyScroller(getContext()));
    } catch (Exception e) 
    {
        e.printStackTrace();
    }
  }

  public class MyScroller extends Scroller 
  {
    public MyScroller(Context context) 
    {
        super(context, new DecelerateInterpolator());
    }

    @Override
    public void startScroll(int startX, int startY, int dx, int dy, int duration) 
    {
        super.startScroll(startX, startY, dx, dy, 1000 /*1 secs*/);
    }
  }
} 
Share:
11,337
Tautvydas
Author by

Tautvydas

Updated on July 18, 2022

Comments

  • Tautvydas
    Tautvydas almost 2 years

    I am writing application that uses ViewPager to host Fragments.

    When I change fragment programmatically the smooth scroll function does not work. I use ViewPager.setCurrentItem(int item, boolean smoothScroll)` method.

    Maybe anyone know a workaround this bug? Maybe with animations?

    EDIT: I am using support package. And the issue is that whether I use ViewPager.setCurrentItem(2, true) or ViewPager.setCurrentItem(2, false) the result is the same. The view switches really fast (not smoothly).

    • Jorge Aguilar
      Jorge Aguilar over 11 years
      First of all, the viewpager ONLY exist on the support package. Now the question would be, what is the problem you are facing ? if you do setCurrentItem(2, false) what it does instead ? can you edit your question to be a little more specific ?
    • MinceMan
      MinceMan over 11 years
      So I put mPager.setCurrentItem(1, true); in a postrunnable to give a hint to the user that the object is a viewpager. The problem is that there is no animation when I put it in the postrunnable which kills the point. Is there another way I could do this?
  • Tautvydas
    Tautvydas over 11 years
    Interesting. You are changing the fragments, is that correct? I don't change fragments themselves just trying to switch between them. I'll try something with this NotifyDataSetChanged() idea. Thanks!
  • samus
    samus over 11 years
    Yes, I'm changing them dynamically. I have 4 half screen panels that are implemented as fragments and hosted inside a ViewPager. Each panel shows the details of an item from the panel to its left (and is why I'm dynamically updating them). I don't think NotifyDataSetChanged should hurt anything if you call it without having actually changed anything beforehand, though I'm not sure if it will help (if it doesn't , maybe you can change something in a fragment very minor, change it back, then call NotifyDataSetChanged, to force it ?).
  • Tautvydas
    Tautvydas about 11 years
    This solution is a nasty one, but should actually work! Thanks, I'll try to implement your suggestion.
  • Iftah
    Iftah about 10 years
    If you use this workaround and ProGuard, you need to add this to your ProGuard config: -keepclassmembers class android.support.v4.view.ViewPager { private android.widget.Scroller mScroller; }
  • SamIAmHarris
    SamIAmHarris almost 5 years
    I see the decelerate interpolator having an effect, but the 1 second delay in startScroll does not seem to do anything on my side.