本文配套视频

  • ViewPager.setCurrentItem的bug演示一
  • ViewPager.setCurrentItem解决方案二

今天做项目用ViewPager.setCurrentItem 方法,如果两个页面相聚比较远,就会闪瞎我的钛合金双眼,中间切换大概20个页面,如下所示: 

setCurrentItem第二个参数设置false,四不四很简单,直接使用如下代码:

ViewPager.setCurrentItem(position,false);
  • 1

很不幸的是,使用上面的代码会出现如下效果,扎心了老铁: 

从第一题点击切换到第十八题,你会发现页面显示空白,如果从第十个页面切换到第十五个页面没事,平时大家估计没有发现这个bug,一般我们使用ViewPager都是底下5个tab页面,从第一个切换到第五个没事,之前我也以为把第二个参数设置false就行,今天才发现,原来如果当页面比较少的时候,大概十个以内,一般没有问题,如果超过十个页面切换就会出现空白,加载不了数据,扎心了,提出解决方案吧,ViewPager滑动使用的是Scroll,咱们把Scroll的滑动时间duration 设置为0就行。

自定义一个Scroll类,用于控制ViewPager滑动速度:

public  class MScroller extends Scroller {private static final Interpolator sInterpolator = new Interpolator() {public float getInterpolation(float t) {t -= 1.0f;return t * t * t * t * t + 1.0f;}};public boolean noDuration;public void setNoDuration(boolean noDuration) {this.noDuration = noDuration;}public MScroller(Context context) {this(context,sInterpolator);}public MScroller(Context context, Interpolator interpolator) {super(context, interpolator);}@Overridepublic void startScroll(int startX, int startY, int dx, int dy, int duration) {if(noDuration)//界面滑动不需要时间间隔super.startScroll(startX, startY, dx, dy, 0);elsesuper.startScroll(startX, startY, dx, dy,duration);}
}
  • 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

上面代码可知:

1)动态判断页面是否需要滑动,如果不需要滑动,设置滑动时间为0;

为方便使用,定义一个辅助类

public class ViewPageHelper {ViewPager viewPager;MScroller scroller;public ViewPageHelper(ViewPager viewPager) {this.viewPager = viewPager;init();}public void setCurrentItem(int item){setCurrentItem(item,true);}public MScroller getScroller() {return scroller;}public void setCurrentItem(int item, boolean somoth){int current=viewPager.getCurrentItem();//如果页面相隔大于1,就设置页面切换的动画的时间为0if(Math.abs(current-item)>1){scroller.setNoDuration(true);viewPager.setCurrentItem(item,somoth);scroller.setNoDuration(false);}else{scroller.setNoDuration(false);viewPager.setCurrentItem(item,somoth);}}private void init(){scroller=new MScroller(viewPager.getContext());Class<ViewPager>cl=ViewPager.class;try {Field field=cl.getDeclaredField("mScroller");field.setAccessible(true);//利用反射设置mScroller域为自己定义的MScrollerfield.set(viewPager,scroller);} catch (NoSuchFieldException e) {e.printStackTrace();}catch (IllegalAccessException e){e.printStackTrace();}}}
  • 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

由上面代码可知:

1)Math.abs(current-item)>1 ,通过数学函数判断页面相隔大于1,就设置页面切换的动画的时间为0。

2)这样每次设置页面的时候,通过 helper 就可以自动选择是否有时间间隔了。

3)但是这样有点麻烦,每次还要手动改,而且使用TabLayout或者ViewPagerIndicator的话,它会自动调用ViewPager的方法,无法使用Helper,所以可以采用自定一个ViewPager,代码如下:

public class SuperViewPager extends ViewPager {private ViewPageHelper helper;public SuperViewPager(Context context) {this(context,null);}public SuperViewPager(Context context, AttributeSet attrs) {super(context, attrs);helper=new ViewPageHelper(this);}@Overridepublic void setCurrentItem(int item) {setCurrentItem(item,true);}@Overridepublic void setCurrentItem(int item, boolean smoothScroll) {MScroller scroller=helper.getScroller();if(Math.abs(getCurrentItem()-item)>1){scroller.setNoDuration(true);super.setCurrentItem(item, smoothScroll);scroller.setNoDuration(false);}else{scroller.setNoDuration(false);super.setCurrentItem(item, 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
  • 31
  • 32
  • 33

至此完美解决了,ViewPager.setCurrentItem切换页面,效果如下: 

解决ViewPager.setCurrentItem中间很多页面切换方案相关推荐

  1. Android 解决ViewPager.setCurrentItem中间很多页面切换问题

    最近项目有个需求是主页包含4个Fragment,但还要求有滑动效果.相信大家第一个就会想到viewPager+fragment进行实现该功能了. 在做完功能后,发现有个问题,就是当我点击底部tab时, ...

  2. 解决viewpager setCurrentItem 白屏问题

    比如你刚刚初始化viewpager数据,每个viewpager里面放的fragment,   设置currentItem  为4  可能就会白屏. 解决方案 viewPager.setOffscree ...

  3. Android 底部导航栏+页面切换

    lzyprime 博客 (github) 更新时间: 2020.12.21 创建时间:2020.11.25 qq及邮箱:2383518170 kotlin & android 笔记 更新 20 ...

  4. ViewPager (下)-- 利用 Fragment 实现美丽的 页面切换

    之前用的ViewPager适用于简单的广告切换,但实现页面间的切换最好是用官方推荐的Fragment来处理. 本人力争做到最简单.最有用,是想以后用到的时候能够方便的拿过来复制就能够了. 效果图:   ...

  5. ViewPager页面切换效果

    ViewPager页面切换效果 运行效果一:                                                                               ...

  6. (仿头条APP项目)3.二级页面首页的ViewPager页面切换

    文章目录 二级页面首页的ViewPager页面切换 效果展示 代码实现 创建几个三级页面Fragment视图 ViewPager的Fragment数据丢失问题 创建fragment_home视图文件 ...

  7. ViewPager实现页面切换

    先贴效果图(每个开关Tab债券.尾随页变化.效果图蓝条添加的用户体验) 首先看总体效果图的布局文件吧(非常easy,就三部分,各自是Tab栏目.定位蓝条.各个页面(是V4包下的ViewPager)) ...

  8. html控制两个页面转换,html页面切换过度效果实现方案_蓝戒的博客

    html页面切换过度效果实现方法很简单,但是对于浏览器的设置有需求,经过测试IE浏览器的默认设置没有问题,但是其他浏览器需要进行设置才可以. 实现方法就是:利用文本头的 标记实现页面过渡效果,具体说明 ...

  9. AngularJs应用页面切换优化方案

    前言 AngularJs被用来开发单页面应用程序(SPA),利用AJAX调用配合页面的局部刷新,可以减少页面跳转,从而获得更好的用户体验.Angular的ngView及其对应的强大路由机制,是实现SP ...

最新文章

  1. Search Help技术
  2. dt测试软件的学习心得,无线网络优化dt测试心得_适合新手入门,高手进阶_5年项目经验实战经验.docx...
  3. [转]写一个块设备驱动(第八章)
  4. ? Generators生成器
  5. JDK8新特性(三)之常用内置函数式接口
  6. 使用Nginx的proxy_cache缓存功能取代Squid(转)
  7. Csharp windowform bindingNavigator,bindingSource,DataGridView簡單分頁:首頁,上一頁,下一頁,末頁...
  8. SpringCloud是什么
  9. CATIA二次开发—强大的Selection
  10. 【Python】Spy++使用
  11. 臭名昭著的Java”
  12. Android Service保活方法总结
  13. 小技巧——阿里个人邮箱登录有问题怎么办?
  14. Unity实现瞄准镜效果
  15. pandas横向运算
  16. 破防了,这4款良心高效的优质软件,着实把我感动到了
  17. Android--Button、TabLayout英文小写自动变为大写的问题
  18. win10:谷歌浏览器如何导出扩展程序
  19. Windows 10环境中安装Snort+Barnyard2+MySQL
  20. 2022年大学应届生破千万,就业形势严峻,打工人准备好了吗?

热门文章

  1. JSP学习笔记(动力节点老杨)(自己总结方便复习)
  2. SQL必备技能:update使用介绍
  3. 任意修改PPT 2007中的剪贴画
  4. 一文读懂雨量传感器的前世今生
  5. Qt雨田哥的斗图神器
  6. 创建型——工厂系列(Factory)day04
  7. EDIUS中视频倒放的快慢特效怎样制作
  8. 进一步谈progress
  9. 今日学习在线编程题:小码哥的属相
  10. Android模仿软键盘实现软键盘的删除功能(逐个删除EditText的输入元素)