The picture carousel control is usually composed of ViewPager and indicator.
Because ViewPager does not support circular page flipping, you need to handle it yourself. When the ViewPager cannot slide forward or backward in the first and last item, we can add an item at the beginning and end of the original list. Add the first item as the last item of the original list, and the last item as the first item of the original list. And when the ViewPager switches to the boundary page, silently changes to the second page or the penultimate page, you can scroll and switch. Use ViewPage.setCurrentItem(int item, boolean smoothScroll) to switch pages immediately.
Index location | Original list | ViewPager display list |
---|---|---|
0 | A | B |
1 | B | A |
2 | B | |
3 | A |
Main code:
//Number of carousels
private int count;
//ViewPager current item
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);
}
...
}
}
/**
* Monitor ViewPager scroll status
*/
@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://No operation
setCurrentPageSilence();
break;
case ViewPager.SCROLL_STATE_DRAGGING://Start dragging
setCurrentPageSilence();
break;
case ViewPager.SCROLL_STATE_SETTLING://Drag final position
break;
}
}
/**
* Switch pages quietly
*/
private void setCurrentPageSilence() {
if (mCurrentItem == 0) {
mViewPager.setCurrentItem(count, false);
} else if(mCurrentItem == count + 1) {
mViewPager.setCurrentItem(1, false);
}
}
In addition, the automatic round robin is realized by the Handler submitting the delayed task, which switches to the next page when the task is running. Also silently changes to the second page when the last page is rotated.
/**
* Backward rotation task
*/
private Runnable mPlayTask = new Runnable() {
@Override
public void run() {
if (mIsAutoPlay) {
if (mCurrentItem == count + 1) {
mCurrentItem = 1;
setCurrentPageSilence();
mHandler.post(this);
} else {
mCurrentItem += 1;
//next page
mViewPager.setCurrentItem(mCurrentItem);
mHandler.postDelayed(this, mDelayTime);
}
}
}
};
Note that the Handler reference is not released, which causes memory leak.