Search code examples
androidanimationandroid-viewpager

Change ViewPager animation duration when sliding programmatically


I'm changing slide with the following code:

viewPager.setCurrentItem(index++, true);

But it changes too fast. Is there a way to set manually the animation speed?


Solution

  • I've wanted to do myself and have achieved a solution (using reflection, however). I haven't tested it yet but it should work or need minimal modification. Tested on Galaxy Nexus JB 4.2.1. You need to use a ViewPagerCustomDuration in your XML instead of ViewPager, and then you can do this:

    ViewPagerCustomDuration vp = (ViewPagerCustomDuration) findViewById(R.id.myPager);
    vp.setScrollDurationFactor(2); // make the animation twice as slow
    

    ViewPagerCustomDuration.java:

    import android.content.Context;
    import android.support.v4.view.ViewPager;
    import android.util.AttributeSet;
    import android.view.animation.Interpolator;
    
    import java.lang.reflect.Field;
    
    public class ViewPagerCustomDuration extends ViewPager {
    
        public ViewPagerCustomDuration(Context context) {
            super(context);
            postInitViewPager();
        }
    
        public ViewPagerCustomDuration(Context context, AttributeSet attrs) {
            super(context, attrs);
            postInitViewPager();
        }
    
        private ScrollerCustomDuration mScroller = null;
    
        /**
         * Override the Scroller instance with our own class so we can change the
         * duration
         */
        private void postInitViewPager() {
            try {
                Field scroller = ViewPager.class.getDeclaredField("mScroller");
                scroller.setAccessible(true);
                Field interpolator = ViewPager.class.getDeclaredField("sInterpolator");
                interpolator.setAccessible(true);
    
                mScroller = new ScrollerCustomDuration(getContext(),
                        (Interpolator) interpolator.get(null));
                scroller.set(this, mScroller);
            } catch (Exception e) {
            }
        }
    
        /**
         * Set the factor by which the duration will change
         */
        public void setScrollDurationFactor(double scrollFactor) {
            mScroller.setScrollDurationFactor(scrollFactor);
        }
    
    }
    

    ScrollerCustomDuration.java:

    import android.annotation.SuppressLint;
    import android.content.Context;
    import android.view.animation.Interpolator;
    import android.widget.Scroller;
    
    public class ScrollerCustomDuration extends Scroller {
    
        private double mScrollFactor = 1;
    
        public ScrollerCustomDuration(Context context) {
            super(context);
        }
    
        public ScrollerCustomDuration(Context context, Interpolator interpolator) {
            super(context, interpolator);
        }
    
        @SuppressLint("NewApi")
        public ScrollerCustomDuration(Context context, Interpolator interpolator, boolean flywheel) {
            super(context, interpolator, flywheel);
        }
    
        /**
         * Set the factor by which the duration will change
         */
        public void setScrollDurationFactor(double scrollFactor) {
            mScrollFactor = scrollFactor;
        }
    
        @Override
        public void startScroll(int startX, int startY, int dx, int dy, int duration) {
            super.startScroll(startX, startY, dx, dy, (int) (duration * mScrollFactor));
        }
    }