AutoScrollViewPager

很多程序有循环播放的界面,比如广告,活动等。这种界面的实现一般情况下会多个元素自动播放,无限循环,网上找了下,主要有两种实现方式:

  • ViewPager有非常多个元素来实现无缝循环
  • 在ViewPager的前后分别插入原来的最后一页和第一页,如下图所示,直接引用别人的图片了:

一般这种页面都会有指示当前页面的小圆点,这个小圆点可以硬编码,也可以使用ViewPagerIndicator来实现,硬编码不太方便,而使用ViewPagerIndicator的话也有一点问题,直接就把第一种方法排除了,第二种方法也没有发现现成的好的实现,所以就自己按这个思路实现了一个,效果如下所示:

因为要在实际的Adapter前后各加一页数据,所以写了一个AutoScrollPagerAdapter封装用户指定的Adapter,并重写了ViewPager的setAdapter方法使这个封装透明化,并重写了getAdapter返回原来的Adapter,这样也兼容了PagerIndicator

对于OnPageChangeListener,由于额外添加了两个页面,OnPageChangeListener中页面的position肯定会有变化,所以需要做下处理,设置一个内部的InnerOnPageChangeListener并重写了setOnPageChangeListener使之透明化

详细实现可以直接看代码:AutoScrollViewPager,重要的地方加了注释,这里就不多说了,以下是主要方法

  • startAutoScroll([intervalInMillis]):自动播放,可以指定播放间隔,单位为ms,如果不指定,采用上一次start时指定的值或默认值2s
  • stopAutoScroll():停止自动播放
  • setInterval(long):播放间隔
  • setScrollFactor(double):页面间切换时间因子,页面切换的时间会乘以这个Factor
  • setOnPageClickListener(AutoScrollViewPager.OnPageClickListener):监听页面点击

有两点需要说一下。

一、OnPageSelected

对用户指定的Adapter的第一页和最后一页会调用两次OnPageSelected,在InnerOnPageChangeListener.onPageSelected中有注释说明。也有解决方法,但这样要么对ViewPagerIndicator会有影响,要么有其他一点很微小的影响,也懒得想其他解决方法,因为感觉影响不大,所以现在还是触发两次。

二、ScrollFactor

对于ScrollFactor,自动播放时默认的滚动速度是很快的,所以添加了这个方法修改滚动速度,先看下ViewPager的代码

1
2
3
4
5
6
7
8
9
10
11
int duration = 0;
velocity = Math.abs(velocity);
if (velocity > 0) {
duration = 4 * Math.round(1000 * Math.abs(distance / velocity));
} else {
final float pageWidth = width * mAdapter.getPageWidth(mCurItem);
final float pageDelta = (float) Math.abs(dx) / (pageWidth + mPageMargin);
duration = (int) ((pageDelta + 1) * 100);
}
duration = Math.min(duration, MAX_SETTLE_DURATION);
mScroller.startScroll(sx, sy, dx, dy, duration);

用户用手滑动翻页时velocity > 0,用代码翻页时velocity = 0,使用的Scroller计算滚动,所以设置了一个自定义的Scroller用来改变duration,但是其实用户手动滑动时的滚动速度还是可以的,只是自动翻页时速度过快,而通过设置Scroller的方法改变duration会同时影响两者,所以在onTouch做了下处理

1
2
3
4
5
6
7
8
9
10
11
12
13
case MotionEvent.ACTION_UP:
// Manually swipe not affected by scroll factor.
if (scroller != null) {
final double lastFactor = scroller.getFactor();
scroller.setFactor(1);
post(new Runnable() {
@Override
public void run() {
scroller.setFactor(lastFactor);
}
});
}
break;

源码:AutoScrollViewPager

作者:AngelDevil
出处:http://www.angeldevil.me
原文链接:http://www.angeldevil.me/2014/10/13/AutoScrollViewPager/

转载请注明出处!