Как автоматически переключаться между страницами ViewPager - программирование
Подтвердить что ты не робот

Как автоматически переключаться между страницами ViewPager

У меня есть приложение для Android, в котором используется ViewPager с двумя страницами Когда активность сначала отображается, я хотел бы представить каждую страницу по очереди пользователю, чтобы они знали, что они могут перебирать между двумя видами. Мне не удалось найти какие-либо документы, описывающие, как это сделать. Я обнаружил PageTransformations, который звучал многообещающе, но пользователь должен проскользнуть первым. Мне нужно, чтобы мои две страницы автоматически прокручивались, как только отобразится первая страница в ViewPager. как достичь желаемого результата?

4b9b3361

Ответ 1

Вы можете использовать Timer для этой цели. Следующий код сам по себе поясняет:

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

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

    }
}

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

Примечание 1: Убедитесь, что вы вызываете метод pageSwitcher после настройки adapter на viewPager правильно внутри метода onCreate вашей активности.

Примечание 2: viewPager будет прокручиваться каждый раз при его запуске. Вы должны обрабатывать его так, чтобы он просматривал все страницы только один раз (когда пользователь просматривает viewPager в первый раз)

Примечание 3: Если вы хотите замедлить скорость прокрутки viewPager, вы можете fooobar.com/questions/60352/....


Расскажите мне в комментариях, если это не поможет вам...

Ответ 2

Вопрос старый, но я надеюсь, что это поможет кому-то Мое решение с использованием Runnable

Короткий ответ

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

Длинный ответ Использование в активности

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

Ответ 3

Я создал проект с открытым исходным кодом на github, в котором реализована автоматическая прокрутка ViewPager, пример диаграммы ниже: auto srcoll viewPager

использование

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

заменить

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

Вызов startAutoScroll(), чтобы начать автоматический прокрутка.

stopAutoScroll(), чтобы остановить автоматическую прокрутку.

Подробнее: https://github.com/Trinea/android-auto-scroll-view-pager

Ответ 4

Ниже приведен метод автоматического переключения страниц через некоторое время (вы можете изменить время согласно вашему требованию)

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

если вы хотите бесконечную прокрутку в viewpager, используйте бесконечный класс прокрутки viewpager из приведенной ниже ссылки и выполняйте незначительные изменения (удалить условие) в интерфейсе Runnable.

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

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

не забудьте отменить таймер в режиме "Разрушить".

Ответ 5

Вы можете использовать setCurrentItem для изменения страницы

Ответ 6

Если вы хотите автоматически просматривать страницы просмотра, но, прежде всего, правильное решение, но после первого запуска автозапуска потребление времени задержки, но это неправильно после автоматического переключения текущего пункта. Я добавляю свой код ниже, он работает правильно 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;
            }
        }
    });

и вот метод:

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

Ответ 7

Если вы собираетесь переключать страницу автоматически, то вам следует отключить пейджинг/перелистывание на ViewPager, потому что, если вы нажмете на страницу, и переключение страниц в это время будет выглядеть не очень хорошо, значит вы заметили, что страница ударилась.

Чтобы отключить пейджинг/перелистывание на ViewPager, вам нужно добавить фрагмент кода ниже со своим пользовательским пейджером просмотра.

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

}

после этого вызовите метод из объекта просмотра пейджера.

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

        }
    }

Класс скроллера для прокрутки страницы плавно

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

}

Ответ 8

Это очень просто. Просто добавьте обработчик внутри метода onPageSelected. определить частный обработчик обработчика = новый обработчик(); на вершине деятельности

 private class MyPageListener implements ViewPager.OnPageChangeListener {


    @Override
    public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

    }

    @Override
    public void onPageSelected(int position) {

        if (position == 0) {

            handler.postDelayed(new Runnable() {
                @Override
                public void run() {
                    viewPager.setCurrentItem(10, false);
                }
            }, 500);

        } else if (position == 11) {

            handler.postDelayed(new Runnable() {
                @Override
                public void run() {
                    viewPager.setCurrentItem(1, false);
                }
            }, 500);
        }

    }

    @Override
    public void onPageScrollStateChanged(int state) {

    }
}

Ответ 9

Вот автопрокрутка, просмотр пейджера

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

}

Вот реализация XML

Вот реализация файла класса

 MovieFeaturedAdapter mMovieFeaturedAdapter = new MovieFeaturedAdapter(getActivity(), mCurrentMovies);
                    vpFeatured.setAdapter(mMovieFeaturedAdapter);