核心思想

  • Android 系统对 ViewPager 的设定是,当滑动停留在最后一页时,不能继续滑,(第一页也是同理),系统并没有支持循环滑动。
  • 通过重写 Touch 事件,表面看上去是实现了循环切页的逻辑,实际上交互起来十分莫名。
  • 于是,完美的做法:依然利用 ViewPager 的特性,只是让它“到达不了边界”。

实现

首先,需要滑动交互的前提是至少有 2 个 Page;这里假设有 5 个 Page,ABCDE。构造完 List 之后,额外添加一页 E 到头部以及一页A到尾部。

1
2
3
4
5
6
7
8
9
10
{
String imageURL = mImageURLs.get(mImageURLs.size() - 1);
ImageView page = createPage(imageURL);
mPages.add(0, page);
}
{
String imageURL = mImageURLs.get(0);
ImageView page = createPage(imageURL);
mPages.add(page);
}

翻页停留到边界时,作响应的矫正 (无动画,默默执行)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
private void correctPage()
{
if(mCurIndex == 0)
{
mCurIndex = mPages.size() - 2;
switchPage(mCurIndex, false);
}
else if(mCurIndex == mPages.size() - 1)
{
mCurIndex = 1;
switchPage(mCurIndex, false);
}
}

// smoothScroll 参数表示是否需要动画
private void switchPage(int index, boolean smoothScroll)
{
mViewPager.setCurrentItem(index % mPages.size(), smoothScroll);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
public class MyPageChangeListener implements OnPageChangeListener
{
@Override
public void onPageSelected(int position)
{
mCurIndex = position % mPages.size();
}

@Override
public void onPageScrolled(int position, float offset, int offsetPixels) {
}

@Override
public void onPageScrollStateChanged(int status)
{
if (mViewPager.getAdapter().getCount() <= 1) {
return;
}

switch (status) {
case 1:
break;
case 2:
break;
case 0:// 滑动结束
correctPage();
break;
}
}
}