How to switch automatically between viewPager pages

后端 未结 8 1226
难免孤独
难免孤独 2020-11-29 08:41

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 kno

相关标签:
8条回答
  • 2020-11-29 08:46

    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);
    
    0 讨论(0)
  • 2020-11-29 08:55

    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);
    
    0 讨论(0)
  • 2020-11-29 08:58

    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.

    0 讨论(0)
  • 2020-11-29 08:59

    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);
        }
    }
    
    0 讨论(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));
        }
    
    }
    
    0 讨论(0)
  • 2020-11-29 09:02

    You can use setCurrentItem to change page

    0 讨论(0)
提交回复
热议问题