24

I have an android application that employs a ViewPager with two pages When the activity first displays i would like to present each page in turn to the user so that they know they can swipe between to two views. I have failed to find any docs describing how to do this. I have discovered PageTransformations which sounded promising but the user has to swipe first. I need my two pages to scroll automatically as soon as the first page in the ViewPager displays. how can a achieve the desired result?

Hector
  • 4,016
  • 21
  • 112
  • 211
  • 1
    u can use timer for doing this.set duration that u want and viewPager.setCurrentItem(position).explain more so that i can help. – TheFlash Jul 12 '13 at 07:56
  • Have a viewpager with two pages, e.g. Left and right page. only when viewpager first displays i would like this sequence of events. a). initailly display Right hand page. b). smooth scroll to left hand page. If possible add a gentle "bump" or overshoot animation at end of smooth scroll – Hector Jul 12 '13 at 09:23
  • wait for me, i will be posting code for that. – Shajeel Afzal Jul 12 '13 at 09:55

9 Answers9

71

You can use Timer for this purpose. The following code is self explanatory:

// ---------------------------------------------------------------------------

Timer timer;
int page = 1;

public void pageSwitcher(int seconds) {
    timer = new Timer(); // At this line a new Thread will be created
    timer.scheduleAtFixedRate(new RemindTask(), 0, seconds * 1000); // delay
                                                                    // in
    // milliseconds
}

    // this is an inner class...
class RemindTask extends TimerTask {

    @Override
    public void run() {

        // As the TimerTask run on a seprate thread from UI thread we have
        // to call runOnUiThread to do work on UI thread.
        runOnUiThread(new Runnable() {
            public void run() {

                if (page > 4) { // In my case the number of pages are 5
                    timer.cancel();
                    // Showing a toast for just testing purpose
                    Toast.makeText(getApplicationContext(), "Timer stoped",
                            Toast.LENGTH_LONG).show();
                } else {
                    mViewPager.setCurrentItem(page++);
                }
            }
        });

    }
}

// ---------------------------------------------------------------------------

Note 1: Make sure that you call pageSwitcher method after setting up adapter to the viewPager properly inside onCreate method of your activity.

Note 2: The viewPager will swipe every time you launch it. You have to handle it so that it swipes through all pages only once (when the user is viewing the viewPager first time)

Note 3: If you further want to slow the scrolling speed of the viewPager, you can follow this answer on StackOverflow.


Tell me in the comments if that could not help you...

Community
  • 1
  • 1
Shajeel Afzal
  • 5,913
  • 6
  • 43
  • 70
  • thanks for your suggestion. i have changed your code as i needed a delay before the transition occurs, however the transition is still very fast! i would have thought i can fix this ViewPager.PageTransformer. – Hector Jul 12 '13 at 10:14
  • @user423199 So, Do you mean that it still didn't solved your problem? – Shajeel Afzal Jul 12 '13 at 10:17
  • it resolves "Half" my problem. whats still not resolved is that by using setCurrentItem the pages switch too fast, i would like that they scroll slower from left page to right page – Hector Jul 12 '13 at 10:21
  • 1
    I hope that this answer can help you for that: http://stackoverflow.com/a/9731345/1773155 – Shajeel Afzal Jul 12 '13 at 10:28
  • yes thanks i just added that code into my application and it works a treat, sadly though it requires min sdk 11 and i need to use min sdk 8 – Hector Jul 12 '13 at 11:01
  • So you should not change your `minSdk` version to 11, you should modify your code so that on previous versions than 11, the speed should remain default, and on `SDK 11` and above you should apply this hack... – Shajeel Afzal Jul 12 '13 at 11:13
  • SHOW ME THE BUTTER! - one thing that is upsetting is when the initial animation runs its NOT "BUTTERY", its JANKY!i am not sure why that is as subsequent scrolls (started manually by swiping) are every smooth – Hector Jul 12 '13 at 11:55
  • Did you mean that when you manually scroll the viewPage it is scrolling slowly now? – Shajeel Afzal Jul 12 '13 at 12:03
  • yes, by setting the Hacked scroller associated with the viewpager in my onCreate() any manual scrolls are perfect both in their speed of transition and smoothness of movement. however the automatic scroll when the screen first displays is "jumpy" – Hector Jul 12 '13 at 12:06
  • I think after first displaying the viewPager to the user using the hack, you should set viewPager back to default. – Shajeel Afzal Jul 12 '13 at 12:09
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/33357/discussion-between-shajeel-afzal-and-user423199) – Shajeel Afzal Jul 12 '13 at 12:09
  • 2
    If someone need to loop through the headlines infinitely just do viewPager.setCurrentItem( (viewPager.getCurrentItem() + 1) % (viewPager.getChildCount() + 1) ); – Bitcoin Cash - ADA enthusiast Jan 29 '14 at 21:33
  • @ShajeelAfzal hi. will the timer stop automatically when the user opens a new fragment? – Lendl Leyba Apr 23 '15 at 04:14
  • Hi @LeiLeyba it depends on how you open a new fragment. I think you should replace fragments. Show us the code that you are trying. – Shajeel Afzal Apr 23 '15 at 09:04
  • Yep, i use replace. So it means that i'm good with the code. Right? – Lendl Leyba Apr 23 '15 at 09:19
  • Yes you should be, you can check to make sure by showing log in onDestroy method of your fragment. – Shajeel Afzal Apr 23 '15 at 09:21
  • 2
    This causes memory to be leaked. – Clive Jefferies Jun 12 '15 at 08:59
  • @CliveJefferies please elaborate and suggest your solution. – Shajeel Afzal Jun 12 '15 at 16:53
  • 2
    When look for memory leaks in the app I am working on, this was a pretty bad offender, due to the use of TimerTask. Here is further explanation: http://www.mopri.de/2010/timertask-bad-do-it-the-android-way-use-a-handler/ – Clive Jefferies Jun 15 '15 at 09:29
  • 1
    If you want smooth scrolling, you can just use the other implementation of "setCurrentItem" method like this - mViewPager.setCurrentItem(page++, true); //where 2nd parameter which is set to true is for "smoothScroll" – Shubhral Jun 03 '16 at 07:00
37

The question is old but I hope it helps someone My solution using Runnable

Short answer

Runnable runnable = new Runnable() {
    public void run() {
        if (myAdapter.getCount() == page) {
            page = 0;
        } else {
            page++;
        }
        viewPager.setCurrentItem(page, true);
        handler.postDelayed(this, delay);
    }
};

Long answer Using in an activity

public class activity extends AppCompatActivity {

    private Handler handler;
    private int delay = 5000; //milliseconds
    private ViewPager viewPager;
    private int page = 0;
    private MyAdapter myAdapter;
    Runnable runnable = new Runnable() {
        public void run() {
            if (myAdapter.getCount() == page) {
                page = 0;
            } else {
                page++;
            }
            viewPager.setCurrentItem(page, true);
            handler.postDelayed(this, delay);
        }
    };

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        handler = new Handler();
        viewPager = (ViewPager) findViewById(R.id.viewPager);
        myAdapter = new MyAdapter(getSupportFragmentManager());
        viewPager.setAdapter(myAdapter);
        viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

            }

            @Override
            public void onPageSelected(int position) {
                page = position;
            }

            @Override
            public void onPageScrollStateChanged(int state) {

            }
        });
    }

    @Override
    protected void onResume() {
        super.onResume();
        handler.postDelayed(runnable, delay);
    }

    @Override
    protected void onPause() {
        super.onPause();
        handler.removeCallbacks(runnable);
    }
}
Luciano Marqueto
  • 1,148
  • 1
  • 15
  • 24
14

I've created a open source project on github, which implements a auto scroll ViewPager, Example diagram below: auto srcoll viewPager

use

<cn.trinea.android.view.autoscrollviewpager.AutoScrollViewPager
    android:id="@+id/view_pager"
    android:layout_width="match_parent"
    android:layout_height="wrap_content" />

replace

<android.support.v4.view.ViewPager
    android:id="@+id/view_pager"
    android:layout_width="match_parent"
    android:layout_height="wrap_content" />

call startAutoScroll() to start auto scroll.

stopAutoScroll() to stop auto scroll.

More: https://github.com/Trinea/android-auto-scroll-view-pager

Community
  • 1
  • 1
Trinea
  • 649
  • 8
  • 10
  • 3
    Almost duplicate of [your answer](http://stackoverflow.com/questions/17167740/android-viewpager-automatically-change-page/22093830#22093830). Stop posting duplicate answer, instead post a single and give posted answer's link here for the reference. – Paresh Mayani Feb 28 '14 at 11:33
  • @Trinea You need to do more work in onMeasure or somewhere where you could measure the size of children. If I want to give wrap content your code fails. so i have to set width height in code on runtime that is really pain in the ass. – AZ_ Mar 19 '14 at 06:43
  • 1
    @AZ_ I think you have used ViewPager in ScrollView, you should add android:fillViewport="true" property for scrollview. http://stackoverflow.com/questions/9034030/viewpager-in-scrollview – Trinea Mar 20 '14 at 09:43
  • @Trinea No dear I am using it in com.handmark.pulltorefresh.library.PullToRefreshGridView https://github.com/chrisbanes/Android-PullToRefresh – AZ_ Mar 21 '14 at 03:34
  • @AZ_, you can test with android.support.v4.view.ViewPager, whether this problem still exists? – Trinea Mar 21 '14 at 08:50
  • Yes because you are not measuring its children size in onMeasure so I manually have to override the ImagePagerAdapter instantiateItem added layout to imageview and then also set the size of viewpager at runtime. @see http://www.youtube.com/watch?v=NYtB6mlu7vA – AZ_ Mar 21 '14 at 09:18
  • Also if you see you demo, it you put finger on the image of view pager it will show nothing and change the image to 4/4 even if you are at 1/4 image. see the demo, tap on the image showing in auto view pager – AZ_ Mar 21 '14 at 09:19
  • @AZ_ yeah, there is something error when viewPager.setSlideBorderMode(AutoScrollViewPager.SLIDE_BORDER_MODE_CYCLE); I have no time to fix it now, do you have any idea? – Trinea Mar 21 '14 at 09:48
  • @Trinea I'll fix it and I'll send it over to you but later dear. Actually we are using viewpager for some different purpose for which it is not designed. I'll read all the source code of Google Native viewpager then I can suggest you something. – AZ_ Mar 23 '14 at 03:00
  • @AZ_ Great! You can commit directly on Github https://github.com/Trinea/android-auto-scroll-view-pager – Trinea Mar 24 '14 at 03:04
  • Please do not use "sexual" images for your demo – FindOut_Quran Oct 24 '15 at 11:13
3

Here is autoscroll view pager

package com.otapp.net.view;

import android.content.Context;
import android.os.Handler;
import android.os.Message;
import android.support.v4.view.MotionEventCompat;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.animation.Interpolator;
import android.widget.Scroller;

import java.lang.ref.WeakReference;
import java.lang.reflect.Field;

public class AutoScrollViewPager extends ViewPager {

    public static final int DEFAULT_INTERVAL = 1500;

    public static final int LEFT = 0;
    public static final int RIGHT = 1;

    public static final int SLIDE_BORDER_MODE_NONE = 0;
    public static final int SLIDE_BORDER_MODE_CYCLE = 1;
    public static final int SLIDE_BORDER_MODE_TO_PARENT = 2;

    private long interval = DEFAULT_INTERVAL;
    private int direction = RIGHT;
    private boolean isCycle = true;
    private boolean stopScrollWhenTouch = true;
    private int slideBorderMode = SLIDE_BORDER_MODE_NONE;
    private boolean isBorderAnimation = true;
    private double autoScrollFactor = 1.0;
    private double swipeScrollFactor = 1.0;

    private Handler handler;
    private boolean isAutoScroll = false;
    private boolean isStopByTouch = false;
    private float touchX = 0f, downX = 0f;
    private float touchY = 0f;

    private CustomDurationScroller scroller = null;

    public static final int SCROLL_WHAT = 0;

    public AutoScrollViewPager(Context paramContext) {
        super(paramContext);
        init();
    }

    public AutoScrollViewPager(Context paramContext, AttributeSet paramAttributeSet) {
        super(paramContext, paramAttributeSet);
        init();
    }

    private void init() {
        handler = new MyHandler(this);
        setViewPagerScroller();
    }

    /**
     * start auto scroll, first scroll delay time is {@link #getInterval()}
     */
    public void startAutoScroll() {
        isAutoScroll = true;
        sendScrollMessage((long) (interval + scroller.getDuration() / autoScrollFactor * swipeScrollFactor));
    }

    /**
     * start auto scroll
     *
     * @param delayTimeInMills first scroll delay time
     */
    public void startAutoScroll(int delayTimeInMills) {
        isAutoScroll = true;
        sendScrollMessage(delayTimeInMills);
    }

    /**
     * stop auto scroll
     */
    public void stopAutoScroll() {
        isAutoScroll = false;
        handler.removeMessages(SCROLL_WHAT);
    }

    /**
     * set the factor by which the duration of sliding animation will change while swiping
     */
    public void setSwipeScrollDurationFactor(double scrollFactor) {
        swipeScrollFactor = scrollFactor;
    }

    /**
     * set the factor by which the duration of sliding animation will change while auto scrolling
     */
    public void setAutoScrollDurationFactor(double scrollFactor) {
        autoScrollFactor = scrollFactor;
    }

    private void sendScrollMessage(long delayTimeInMills) {
        /** remove messages before, keeps one message is running at most **/
        handler.removeMessages(SCROLL_WHAT);
        handler.sendEmptyMessageDelayed(SCROLL_WHAT, delayTimeInMills);
    }

    /**
     * set ViewPager scroller to change animation duration when sliding
     */
    private void setViewPagerScroller() {
        try {
            Field scrollerField = ViewPager.class.getDeclaredField("mScroller");
            scrollerField.setAccessible(true);
            Field interpolatorField = ViewPager.class.getDeclaredField("sInterpolator");
            interpolatorField.setAccessible(true);

            scroller = new CustomDurationScroller(getContext(), (Interpolator) interpolatorField.get(null));
            scrollerField.set(this, scroller);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * scroll only once
     */
    public void scrollOnce() {
        PagerAdapter adapter = getAdapter();
        int currentItem = getCurrentItem();
        int totalCount;
        if (adapter == null || (totalCount = adapter.getCount()) <= 1) {
            return;
        }

        int nextItem = (direction == LEFT) ? --currentItem : ++currentItem;
        if (nextItem < 0) {
            if (isCycle) {
                setCurrentItem(totalCount - 1, isBorderAnimation);
            }
        } else if (nextItem == totalCount) {
            if (isCycle) {
                setCurrentItem(0, isBorderAnimation);
            }
        } else {
            setCurrentItem(nextItem, true);
        }
    }

    /**
     * <ul>
     * if stopScrollWhenTouch is true
     * <li>if event is down, stop auto scroll.</li>
     * <li>if event is up, start auto scroll again.</li>
     * </ul>
     */

    boolean consumeTouch = false;

    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        int action = MotionEventCompat.getActionMasked(ev);

        if (stopScrollWhenTouch) {
            if ((action == MotionEvent.ACTION_DOWN) && isAutoScroll) {
                isStopByTouch = true;
                stopAutoScroll();
            } else if (ev.getAction() == MotionEvent.ACTION_UP && isStopByTouch) {
                startAutoScroll();
            }
        }

        if (slideBorderMode == SLIDE_BORDER_MODE_TO_PARENT || slideBorderMode == SLIDE_BORDER_MODE_CYCLE) {
            touchX = ev.getX();
            if (ev.getAction() == MotionEvent.ACTION_DOWN) {
                downX = touchX;
                touchY = ev.getY();
            } else if (action == MotionEvent.ACTION_UP) {
                consumeTouch = Math.abs(touchY - ev.getY()) > 0;
            }

            int currentItem = getCurrentItem();
            PagerAdapter adapter = getAdapter();
            int pageCount = adapter == null ? 0 : adapter.getCount();
            /**
             * current index is first one and slide to right or current index is last one and slide to left.<br/>
             * if slide border mode is to parent, then requestDisallowInterceptTouchEvent false.<br/>
             * else scroll to last one when current item is first one, scroll to first one when current item is last
             * one.
             */
            if ((currentItem == 0 && downX <= touchX) || (currentItem == pageCount - 1 && downX >= touchX)) {
                if (slideBorderMode == SLIDE_BORDER_MODE_TO_PARENT) {
                    getParent().requestDisallowInterceptTouchEvent(false);
                } else {
                    if (pageCount > 1) {
                        setCurrentItem(pageCount - currentItem - 1, isBorderAnimation);
                    }
                    getParent().requestDisallowInterceptTouchEvent(true);
                }
                return super.dispatchTouchEvent(ev);
            }
        }
        if (consumeTouch) {
            getParent().requestDisallowInterceptTouchEvent(true);
        } else {
            getParent().requestDisallowInterceptTouchEvent(false);
            if (stopScrollWhenTouch)
                startAutoScroll();
        }

        return super.dispatchTouchEvent(ev);
    }

    private static class MyHandler extends Handler {

        private final WeakReference<AutoScrollViewPager> autoScrollViewPager;

        public MyHandler(AutoScrollViewPager autoScrollViewPager) {
            this.autoScrollViewPager = new WeakReference<AutoScrollViewPager>(autoScrollViewPager);
        }

        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);

            switch (msg.what) {
                case SCROLL_WHAT:
                    AutoScrollViewPager pager = this.autoScrollViewPager.get();
                    if (pager != null) {
                        pager.scroller.setScrollDurationFactor(pager.autoScrollFactor);
                        pager.scrollOnce();
                        pager.scroller.setScrollDurationFactor(pager.swipeScrollFactor);
                        pager.sendScrollMessage(pager.interval + pager.scroller.getDuration());
                    }
                default:
                    break;
            }
        }
    }

    public long getInterval() {
        return interval;
    }

    public void setInterval(long interval) {
        this.interval = interval;
    }

    public int getDirection() {
        return (direction == LEFT) ? LEFT : RIGHT;
    }

    public void setDirection(int direction) {
        this.direction = direction;
    }

    public boolean isCycle() {
        return isCycle;
    }

    public void setCycle(boolean isCycle) {
        this.isCycle = isCycle;
    }

    public boolean isStopScrollWhenTouch() {
        return stopScrollWhenTouch;
    }

    public void setStopScrollWhenTouch(boolean stopScrollWhenTouch) {
        this.stopScrollWhenTouch = stopScrollWhenTouch;
    }

    public int getSlideBorderMode() {
        return slideBorderMode;
    }

    public void setSlideBorderMode(int slideBorderMode) {
        this.slideBorderMode = slideBorderMode;
    }

    public boolean isBorderAnimation() {
        return isBorderAnimation;
    }

    public void setBorderAnimation(boolean isBorderAnimation) {
        this.isBorderAnimation = isBorderAnimation;
    }

    public class CustomDurationScroller extends Scroller {

        private double scrollFactor = 1;

        public CustomDurationScroller(Context context) {
            super(context);
        }

        public CustomDurationScroller(Context context, Interpolator interpolator) {
            super(context, interpolator);
        }

        // @SuppressLint("NewApi")
        // public CustomDurationScroller(Context context, Interpolator interpolator, boolean flywheel){
        // super(context, interpolator, flywheel);
        // }

        public void setScrollDurationFactor(double scrollFactor) {
            this.scrollFactor = scrollFactor;
        }

        @Override
        public void startScroll(int startX, int startY, int dx, int dy, int duration) {
            super.startScroll(startX, startY, dx, dy, (int) (duration * scrollFactor));
        }
    }

}

Here is xml implementation

Here is class file implementation

 MovieFeaturedAdapter mMovieFeaturedAdapter = new MovieFeaturedAdapter(getActivity(), mCurrentMovies);
                    vpFeatured.setAdapter(mMovieFeaturedAdapter);
Jitendra
  • 3,608
  • 2
  • 17
  • 19
2

Below method is use to switch pages automatically after some time (you can modify time as per your requirement)

 private void timer() {
                timer = new Timer();
                timer.scheduleAtFixedRate(new TimerTask() {
                    @Override
                    public void run() {
                        runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                if (currentPage == NUM_PAGES - 1) {
                                    currentPage = 0;
                                }
                                view.setCurrentItem(currentPage++, true);
                            }
                        });
                    }
                }, 500, 5000);
            }

if want to endless scroll in viewpager use infinite scroll viewpager class from below provided link and do minor changes (remove condition) in Runnable interface.

runOnUiThread(new Runnable() {
                                @Override
                                public void run() {

                                    view.setCurrentItem(currentPage++, true);
                                }
                            });

also,don't forget to cancel timer on Destroy view.

Hitesh Dhamshaniya
  • 2,088
  • 2
  • 16
  • 23
Rucha Bhatt Joshi
  • 822
  • 1
  • 15
  • 38
1

You can use setCurrentItem to change page

Ivan
  • 703
  • 5
  • 9
  • i can, however the transition between pages is to fast. how do i control the duration of the transition from left to right page? – Hector Jul 12 '13 at 09:51
0

If you want to autoplay viewpager pages but above all solution is correct but after autoplay first item consume delay time but it is wrong after autoplay current item switch quickly. I am adding my code below it is working correctly autoplay/pause.

        @Override
        public void onClick(View v) {

            if (!isAutoPlay) {              
                img_autoplay.setImageResource(R.drawable.pause);
                int currentcount = getModel().getCurrentIndex();
                currentcount++;
                getMainImage().setCurrentItem(currentcount);
                autoPlay(getMainImage());
                isAutoPlay = true;
            } else {
                img_autoplay.setImageResource(R.drawable.auto_play);
                isAutoPlay = false;
            }
        }
    });

and here is method:

    viewPager.postDelayed(new Runnable() {
        @Override
        public void run() {
            try {
                if (myAdapter != null
                        && viewPager.getAdapter().getCount() > 0
                        && isAutoPlay) {
                    getWindow().addFlags(
                            WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
                    int currentcount = getModel().getCurrentIndex();
                    currentcount++;
                    viewPager.setCurrentItem(currentcount);

                    if (getModel().isLastCard()) {
                        final Handler handler = new Handler();
                        handler.postDelayed(new Runnable() {
                            @Override
                            public void run() {
                                isAutoPlay = false;
                                packFinished();
                                getWindow()
                                        .clearFlags(
                                                WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
                            }
                        }, 6000);
                    }
                    autoPlay(viewPager);
                }
            } catch (Exception e) {

            }
        }
    }, 6000);
Bhavinkumar Patel
  • 515
  • 1
  • 12
  • 28
0

If you are going to switch page automatically then you should disable paging/swiping on ViewPager because if you touch on page and that time page switching then it's not look good means you observed page struck.

To disable paging/swiping on ViewPager,you need to add below code snippet with you custom view pager.

import android.content.Context;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.animation.Interpolator;

import java.lang.reflect.Field;

public class ViewPagerCustomDuration extends ViewPager {

    private boolean swipeable = false;

    public ViewPagerCustomDuration(Context context) {
        super(context);
        postInitViewPager();
    }

    public ViewPagerCustomDuration(Context context, AttributeSet attrs) {
        super(context, attrs);
        postInitViewPager();
    }

    public void setSwipeable(boolean swipeable) {
        this.swipeable = swipeable;
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (this.swipeable) {
            return super.onTouchEvent(event);
        }

        return false;
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent event) {
        if (this.swipeable) {
            return super.onInterceptTouchEvent(event);
        }

        return false;
    }

    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);
    }

}

after that,call method from view pager object.

import android.os.Bundle;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.widget.Toast;

import java.util.Timer;
import java.util.TimerTask;



public class MainActivity extends AppCompatActivity {
    ViewPagerCustomDuration viewPager;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main_3);

        viewPager = (ViewPagerCustomDuration) findViewById(R.id.viewpager);
        viewPager.setScrollDurationFactor(2);
        viewPager.setAdapter(new CustomPagerAdapter(this));
        viewPager.setSwipeable(false);
        pageSwitcher(5);

        viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

            }

            @Override
            public void onPageSelected(int position) {
            }

            @Override
            public void onPageScrollStateChanged(int state) {

            }
        });

    }

    Timer timer;
    int page = 1;

    public void pageSwitcher(int seconds) {
        timer = new Timer(); // At this line a new Thread will be created
        timer.scheduleAtFixedRate(new RemindTask(), 0, seconds * 1000); // delay
        // in
        // milliseconds
    }

    // this is an inner class...
    class RemindTask extends TimerTask {

        @Override
        public void run() {

            // As the TimerTask run on a seprate thread from UI thread we have
            // to call runOnUiThread to do work on UI thread.
            runOnUiThread(new Runnable() {
                public void run() {

                    if (page > 4) { // In my case the number of pages are 5
//                        timer.cancel();
                        page = 0;
                        viewPager.setCurrentItem(page++);
                        // Showing a toast for just testing purpose
                        Toast.makeText(getApplicationContext(), "Timer stoped",
                                Toast.LENGTH_LONG).show();
                    } else {
                        viewPager.setCurrentItem(page++);
                    }
                }
            });

        }
    }

Scroller class for scroll page smoothly

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));
    }

}
ViramP
  • 1,659
  • 11
  • 11
0

For new viewPage2 you can use below code

fun ViewPager2.enableAutoScroll(totalPages: Int): Timer {
    val autoTimerTask = Timer()
    var currentPageIndex = currentItem
    autoTimerTask.schedule(object : TimerTask() {
        override fun run() {
            currentItem = currentPageIndex++
            if (currentPageIndex == totalPages) currentPageIndex = 0
        }
    }, 0, DELAY_FOUR_SECONDS)

    // Stop auto paging when user touch the view
    getRecyclerView().setOnTouchListener { _, event ->
        if (event.action == MotionEvent.ACTION_DOWN) autoTimerTask.cancel()
        false
    }

    return autoTimerTask // Return the reference for cancel
}

fun ViewPager2.getRecyclerView(): RecyclerView {
    val recyclerViewField = ViewPager2::class.java.getDeclaredField("mRecyclerView")
    recyclerViewField.isAccessible = true
    return recyclerViewField.get(this) as RecyclerView
}
Jayesh
  • 101
  • 6