图片轮播控件通常由ViewPager和指示器组成。
因为ViewPager并不支持循环翻页,需要自己去处理。当ViewPager在第一项和最后一项时不能向前或向后滑动,那我们可以在原列表首尾各增加一项。增加首项为原列表的最后一项,尾项为原列表的第一项。并在ViewPager切换到边界页时,静默地更改到第二页或倒数第二页,就可以循环滚动切换了。使用了ViewPage.setCurrentItem(int item, boolean smoothScroll) 立即切换页面。
索引位置 | 原列表 | ViewPager展示列表 |
---|---|---|
0 | A | B |
1 | B | A |
2 | B | |
3 | A |
主要代码:
//轮播图数量
private int count;
//ViewPager当前项
private int mCurrentItem;
private void setImageList(List<?> imageUrls) {
...
for (int i = 0; i <= count + 1; i ++) {
...
Object path;
if (i == 0) {
path = imageUrls.get(count - 1);
} else if (i == count + 1) {
path = imageUrls.get(0);
} else {
path = imageUrls.get(i - 1);
}
...
}
}
/**
* 监听ViewPager滚动状态
*/
@Override
public void onPageScrollStateChanged(int state) {
Log.i(tag, "onPageScrollStateChanged state=" + state);
if (mOnPageChangeListener != null) {
mOnPageChangeListener.onPageScrollStateChanged(state);
}
switch (state) {
case ViewPager.SCROLL_STATE_IDLE://无操作
setCurrentPageSilence();
break;
case ViewPager.SCROLL_STATE_DRAGGING://开始拖动
setCurrentPageSilence();
break;
case ViewPager.SCROLL_STATE_SETTLING://拖动最终位置
break;
}
}
/**
* 静静地切换页面
*/
private void setCurrentPageSilence() {
if (mCurrentItem == 0) {
mViewPager.setCurrentItem(count, false);
} else if(mCurrentItem == count + 1) {
mViewPager.setCurrentItem(1, false);
}
}
此外自动轮播是通过Handler提交延时任务来实现的,运行任务时切换到下一页。同样在轮播到最后一页时静默地更改到第二页。
/**
* 向后轮播任务
*/
private Runnable mPlayTask = new Runnable() {
@Override
public void run() {
if (mIsAutoPlay) {
if (mCurrentItem == count + 1) {
mCurrentItem = 1;
setCurrentPageSilence();
mHandler.post(this);
} else {
mCurrentItem += 1;
//下一页
mViewPager.setCurrentItem(mCurrentItem);
mHandler.postDelayed(this, mDelayTime);
}
}
}
};
这里要注意Handler引用没释放导致内存泄漏的问题。