https://github.com/qingse/CircleIndicator 是图片播放开源库,今天来使用其中的LoopViewPager来实现轮播。
1、加载布局时在LoopViewPager构造方法中调用
super.addOnPageChangeListener(onPageChangeListener);
下面这个方法调用了CircleIndicator的监听器:
@Override
public void onPageSelected(int position) {
int realPosition = mAdapter.toRealPosition(position);
if (mPreviousPosition != realPosition) {
mPreviousPosition = realPosition;
if (mOnPageChangeListeners != null) {
for (int i = 0; i < mOnPageChangeListeners.size(); i++) {
OnPageChangeListener listener = mOnPageChangeListeners.get(i);
if (listener != null) {
listener.onPageSelected(realPosition);
}
}
}
}
}
在CircleIndicator构造方法中初始化自定义indicator;
2、LoopPagerAdapterWrapper继承自PagerAdapter;
重写PagerAdapter,定义私有属性 int mSize,在构造方法中传入数据,将viewpager的实际页面数赋值给mSize;
3、在LoopViewPagerFragment的onViewCreated方法中调用
viewpager.setAdapter(new SamplePagerAdapter());
将重写的PagerAdapter赋值给LoopPagerAdapterWrapper的私有属性PagerAdapter mAdapter;
接下来会调用LoopPagerAdapterWrapper中的这个方法,把viewpager 的页面数量在实际数量的基础上加2:
@Override
public int getCount() {
int count = getRealCount();
return mBoundaryLooping ? count + 2 : count;
}
传入自定义的PagerAdapter,在setAdapter中调用setCurrentItem(0,false);
public void setCurrentItem(int item, boolean smoothScroll) {
int realItem = mAdapter.toInnerPosition(item);
super.setCurrentItem(realItem, smoothScroll);
}
下面这个方法判断是否轮播,如果是,就将position加1
public int toInnerPosition(int realPosition) {
int position = (realPosition + 1);
return mBoundaryLooping ? position : realPosition;
}
4、接下来调用
indicator.setViewPager(viewpager);
public void setViewPager(ViewPager viewPager) {
mViewpager = viewPager;
if (mViewpager != null && mViewpager.getAdapter() != null) {
mLastPosition = -1;
createIndicators();
mViewpager.removeOnPageChangeListener(mInternalPageChangeListener);
mViewpager.addOnPageChangeListener(mInternalPageChangeListener);
mInternalPageChangeListener.onPageSelected(mViewpager.getCurrentItem());
}
}
这个方法中添加了CircleIndicator的监听器,用来绘制指示器小圆点。
5、接下来调用到LoopPagerAdapterWrapper中的instantiateItem方法
@Override
public Object instantiateItem(ViewGroup container, int position) {
int realPosition = (mAdapter instanceof FragmentPagerAdapter
|| mAdapter instanceof FragmentStatePagerAdapter) ? position
: toRealPosition(position);
if (mBoundaryCaching) {
ToDestroy toDestroy = mToDestroy.get(position);
if (toDestroy != null) {
mToDestroy.remove(position);
return toDestroy.object;
}
}
return mAdapter.instantiateItem(container, realPosition);
}
这个方法中把position变换为viewpager页面显示时实际的position。
这个方法最后调用了自定义的PagerAdapter中的instantiateItem方法,在这个方法中去初始化每个viewpager中的每个页面就可以了。
实现循环的要点在于LoopPagerAdapterWrapper中的下列方法:
1、 getCount() ,设置viewpager的页面数为实际数量加2;
2、toInnerPosition(realPosition)和toRealPosition(position),这两个方法,设置当页面在0时继续向左滑动,页面在最后一张时继续向右滑动时的页面处理。