Android 는 ViewPager 를 계승 하지 않 고 자동 스크롤 페이지 넘 기기 기능 을 수행 합 니 다.

5564 단어 androidviewpager
ViewPager 를 계승 하여 자동 으로 스크롤 하 는 예 가 이미 많 지만,때때로 우 리 는 계승 을 사용 하고 싶 지 않다.예 를 들 어 하나의 클래스 가 ViewPager 를 계승 하거나 과거의 코드 를 변경 하고 싶 지 않다.
외부 클래스 를 사용 하여 ViewPager 자동 페이지 넘 기기 기능 을 제공 합 니 다.코드 바로 올 리 기:
package lx.af.utils.ViewUtils;

import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;

import java.util.concurrent.TimeUnit;

/**
 * author: lx
 * date: 15-12-15
 *
 * helper to make ViewPager auto scroll
 */
public class ViewPagerAutoFlipper implements
        ViewPager.OnPageChangeListener {

    private static final long DEFAULT_FLIP_INTERVAL = TimeUnit.SECONDS.toMillis(3);

    private ViewPager mViewPager;
    private boolean mAutoFlip = false;
    private long mFlipInterval = DEFAULT_FLIP_INTERVAL;
    private long mLastFlipTime;
    private int mScrollState = ViewPager.SCROLL_STATE_IDLE;
    private int mPosition;

    public static ViewPagerAutoFlipper newInstance(ViewPager pager) {
        return new ViewPagerAutoFlipper(pager);
    }

    public ViewPagerAutoFlipper(ViewPager pager) {
        mViewPager = pager;
        mViewPager.addOnPageChangeListener(this);
        mPosition = mViewPager.getCurrentItem();
    }

    /**
     * @param interval auto flip interval, in millis
     */
    public ViewPagerAutoFlipper setInterval(long interval) {
        if (interval > 0) {
            mFlipInterval = interval;
        } else {
            throw new IllegalArgumentException("interval should be positive");
        }
        return this;
    }

    /**
     * @return true if ViewPager is auto flipping; false otherwise
     */
    public boolean isAutoFlip() {
        return mAutoFlip;
    }

    /**
     * start ViewPager auto flip
     */
    public void start() {
        if (mViewPager != null) {
            mAutoFlip = true;
            mViewPager.removeCallbacks(mFlipRunnable);
            mViewPager.postDelayed(mFlipRunnable, mFlipInterval);
        }
    }

    /**
     * stop ViewPager auto flip.
     * should always call this in Activity.onDestroy to release handler callbacks,
     * or mem leak may occur.
     */
    public void stop() {
        mAutoFlip = false;
        if (mViewPager != null) {
            mViewPager.removeCallbacks(mFlipRunnable);
        }
    }

    /**
     * reset to init state.
     * should be called after {@link ViewPager#setAdapter(PagerAdapter)}
     */
    public void reset() {
        if (mViewPager != null) {
            mViewPager.removeCallbacks(mFlipRunnable);
            mViewPager.removeOnPageChangeListener(this);
            mViewPager.addOnPageChangeListener(this);
            mPosition = mViewPager.getCurrentItem();
            mLastFlipTime = 0;
            mScrollState = ViewPager.SCROLL_STATE_IDLE;
            mViewPager.postDelayed(mFlipRunnable, mFlipInterval);
        }
    }

    @Override
    public void onPageSelected(int position) {
        mPosition = position;
        mLastFlipTime = System.currentTimeMillis();
    }

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

    @Override
    public void onPageScrollStateChanged(int state) {
        mScrollState = state;
    }

    private boolean canAutoFlip() {
        if (mViewPager == null || mViewPager.getAdapter() == null) {
            return false;
        }
        long interval = System.currentTimeMillis() - mLastFlipTime;
        if (interval < mFlipInterval - 300) {
            // postDelayed() is not so accurate about delay time,
            // we minus 300 to avoid post too soon caused by the deviation
            mViewPager.removeCallbacks(mFlipRunnable);
            mViewPager.postDelayed(mFlipRunnable, mFlipInterval - interval);
            return false;
        }
        return mAutoFlip && mScrollState == ViewPager.SCROLL_STATE_IDLE;
    }

    private Runnable mFlipRunnable = new Runnable() {
        @Override
        public void run() {
            if (mViewPager == null) {
                // unlikely
                return;
            }
            if (mViewPager.getWindowToken() == null) {
                // window token no longer valid, exit loop
                mViewPager.removeCallbacks(mFlipRunnable);
                mViewPager.removeOnPageChangeListener(ViewPagerAutoFlipper.this);
                return;
            }

            if (canAutoFlip()) {
                int count = mViewPager.getAdapter().getCount();
                int next = (mPosition + 1 == count) ? 0 : mPosition + 1;
                mViewPager.setCurrentItem(next);
            }
            if (mAutoFlip) {
                mViewPager.removeCallbacks(mFlipRunnable);
                mViewPager.postDelayed(mFlipRunnable, mFlipInterval);
            }
        }
    };

}

사용 도 간단 하 다.
또는
    ViewPagerAutoFlipper.newInstance(mViewPager).setInterval(2000).start();

코드 는 간단 합 니 다.중요 한 문 제 는 Runnable+postDelayed()의 순환 을 어떻게 종료 하 는 지 판단 하 는 것 입 니 다.ViewPager 를 사용 할 수 없습니다.아직 종료 되 지 않 았 다 면 현재 Activity 가 유출 될 수 있 습 니 다.
처음에는 Activity 의 onDestroy()방법 에서 flipper.stop()을 명시 적 으로 호출 했 는데 나중에 이렇게 하 는 것 이 너무 우아 하지 않다 고 생각 하여 window token 이 사용 할 수 있 는 지 판단 하 는 것 으로 바 뀌 었 다.
지금 은 스스로 측정 할 수 있 으 니 다른 문제 가 있 는 지 모르겠다.
코드 는 내 Android App 프레임 에 수 록 됩 니 다:
https://github.com/liuxu0703/AppFrame/blob/master/appframe/src/main/java/lx/af/utils/ViewUtils/ViewPagerAutoFlipper.java
수준 이 제한 되 어 있 으 니 문제 가 있 으 면 지적 해 주세요~.

좋은 웹페이지 즐겨찾기