https://rainmoth.github.io/posts/A181005.html
Android ViewPager的无限循环与自动滚动实现
前言
关于ViewPager时Android开发时经常要用到的控件,但系统提供的ViewPager往往总有一些功能限制,如不能无限循环,不能自动滚动,今天就介绍ViewPager无限循环和自动滚动的不同实现。
实现思路
实现方式有很多种,具体如下,后面会分析各种实现方式的优缺点。
无限循环方式
更改Adapter实现方式
即getCount返回Integer.MAX_VALUE
核心代码(这种方式其实是一种伪无限循环):
| 1 | private MyPageAdapter extends PageAdapter { | 
处理数据源
即让ViewPager绑定的数据源模拟出一个循环效果即可,真实数据源唯0123,将其变为301230);
核心代码:
| 1 | // 绑定到ViewPager的数据源 | 
从OnPageChangeListener入手
当滑动到临界值时,主动调用ViewPager的setCurrentItem方法;
具体实现思路如下(只是我的思路尚未代码验证):
| 1 | // 数据源 | 
不足之处:
采用方法1时,当调用ViewPager的setCurrentItem方法时会造成ANR(只有在onCreate中调用不回出现),解决方法,可设置一个比较大的值,而不采用Integer.MAX_VALUE;
采用方法2和3时,
- 需要解决最后一个到第一个的闪屏问题,我的思路是采用handler来延时处理;
- 需要解决手动滑动时如何处理
自动滚动实现方式
自动滚动逻辑功能要求
- 手动滚动开始时,自动滚动暂停;
- 手动滚动结束时,自动滚动开始;
上面两个是通用处理,也就是说,不管哪种实现方式,都要考虑。
自动滚动实现方式
- 利用Handler来实现自动滚动 - 代码实现如下(核心代码如下): - 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
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51- // 要自动滚动的ViewPager 
 private ViewPager viewPager;
 // 定义是否开启自动滚动,默认开启
 private boolean isAutoPlay = true;
 // 默认自动滚动任务延时两秒执行
 private int delayTime = 2000;
 // 定义处理自动滚动的handler
 private Handler handler = new Handler();
 // 当前ViewPager展示页
 private int currentItem;
 /**
 * 开启自动滚动的方法
 */
 private void startAutoPlay() {
 isAutoPlay = true;
 handler.removeCallbacks(task);
 handler.postDelayed(task, delayTime)
 }
 /**
 * 暂停自动滚动
 */
 public pauseAutoPlay() {
 isAutoPlay = false;
 handler.removeCallbacks(task);
 }
 /**
 * 自动滚动核心代码
 */
 private final Runnable task = new Runnable() {
 
 public void run() {
 if (isAutoPlay) {
 // 自动滚动逻辑处理
 currentItem = viewPager.getCurrentItem();
 currentItem++;
 if(currentItem == randyPagerAdapter.getCount() -1) {
 currentItem = 0;
 viewPager.setCurrentItem(currentItem);
 handler.postDelayed(this, delayTime);
 } else {
 viewPager.setCurrentItem(currentItem);
 handler.postDelayed(this, delayTime);
 }
 } else {
 handler.postDelayed(this, delayTime);
 }
 }
 };
- 利用定时任务(Timer和TimerTask)来实现 - 代码实现(核心代码如下): - 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- private static final int DISPLAY_TIME = 3000; 
 private Handler hander = new Handler();
 private Timer timer = new Timer();
 private TimerTask timerTask;
 private ViewPager mViewPager;
 private Runnable runable = new Runnable() {
 
 public void run() {
 //true表示平滑滚动
 mViewPager.setCurrentItem(mViewPager.getCurrentItem() + 1, true);
 }
 };
 public void startScroll() {
 timerTask = new TimerTask() {
 
 public void run() {
 hander.post(runable);
 }
 };
 timer.schedule(timerTask, DISPLAY_TIME, DISPLAY_TIME);
 }
 public void stopScroll() {
 timerTask.cancel();
 timerTask = null;
 }- 总结- 在处理无限循环时,核心思路就是对临界值的处理,当然也可以通过方法1来绕过这种处理,但要注意一点就是怎么设置getCount的返回值以达到最优的性能;
- 在处理自动滚动时,无非就是通过handler的postDelayed方法的特性以及Android定义的定时器进行处理。