package me.qixingchen.mdbilibili.widget; import android.content.Context; import android.support.v4.view.PagerAdapter; import android.support.v4.view.ViewPager; import android.util.AttributeSet; import java.util.ArrayList; import java.util.List; /** * Created by qixingchen on 15/12/4. * pager无限循环 */ public class LoopViewPager extends ViewPager { private static final boolean DEFAULT_BOUNDARY_CASHING = false; private List<OnPageChangeListener> mOnPageChangeListeners = new ArrayList<>(); private LoopPagerAdapter mAdapter; private boolean mBoundaryCaching = DEFAULT_BOUNDARY_CASHING; private OnPageChangeListener onPageChangeListener = new OnPageChangeListener() { private float mPreviousOffset = -1; private float mPreviousPosition = -1; @Override public void onPageSelected(int position) { int realPosition = mAdapter.toRealPosition(position); if (mPreviousPosition != realPosition) { mPreviousPosition = realPosition; for (OnPageChangeListener listener : mOnPageChangeListeners) { listener.onPageSelected(realPosition); } } } @Override public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { int realPosition = position; if (mAdapter == null) { return; } if (mAdapter != null) { realPosition = mAdapter.toRealPosition(position); if (positionOffset == 0 && mPreviousOffset == 0 && (position == 0 || position == mAdapter.getCount() - 1)) { setCurrentItem(realPosition, false); } } mPreviousOffset = positionOffset; for (OnPageChangeListener listener : mOnPageChangeListeners) { if (realPosition != mAdapter.getRealCount() - 1) { listener.onPageScrolled(realPosition, positionOffset, positionOffsetPixels); } else { if (positionOffset > .5) { listener.onPageScrolled(0, 0, 0); } else { listener.onPageScrolled(realPosition, 0, 0); } } } } @Override public void onPageScrollStateChanged(int state) { if (mAdapter != null) { int position = LoopViewPager.super.getCurrentItem(); int realPosition = mAdapter.toRealPosition(position); if (state == ViewPager.SCROLL_STATE_IDLE && (position == 0 || position == mAdapter.getCount() - 1)) { setCurrentItem(realPosition, false); } } for (OnPageChangeListener listener : mOnPageChangeListeners) { listener.onPageScrollStateChanged(state); } } }; public LoopViewPager(Context context) { super(context); init(); } public LoopViewPager(Context context, AttributeSet attrs) { super(context, attrs); init(); } /** * helper function which may be used when implementing FragmentPagerAdapter * * @param position * @param count * * @return (position-1)%count */ public static int toRealPosition(int position, int count) { position = position - 1; if (position < 0) { position += count; } else { position = position % count; } return position; } /** * If set to true, the boundary views (i.e. first and last) will never be destroyed * This may help to prevent "blinking" of some views * * @param flag */ public void setBoundaryCaching(boolean flag) { mBoundaryCaching = flag; if (mAdapter != null) { mAdapter.setBoundaryCaching(flag); } } @Override public PagerAdapter getAdapter() { return mAdapter != null ? mAdapter.getRealAdapter() : mAdapter; } @Override public void setAdapter(PagerAdapter adapter) { mAdapter = new LoopPagerAdapter(adapter); mAdapter.setBoundaryCaching(mBoundaryCaching); super.setAdapter(mAdapter); setCurrentItem(0, false); } @Override public int getCurrentItem() { return mAdapter != null ? mAdapter.toRealPosition(super.getCurrentItem()) : 0; } ; @Override public void setCurrentItem(int item) { if (getCurrentItem() != item) { setCurrentItem(item, true); } } public void setCurrentItem(int item, boolean smoothScroll) { int realItem = mAdapter.toInnerPosition(item); super.setCurrentItem(realItem, smoothScroll); } @Override public void addOnPageChangeListener(OnPageChangeListener listener) { mOnPageChangeListeners.add(listener); } private void init() { super.addOnPageChangeListener(onPageChangeListener); } }