本文配套视频

  • 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. Delphi开发的IOCP测试Demo以及使用说明。
  2. Xamarin.Android部署失败
  3. cannot import name '_imaging' from 'PIL'
  4. 试用了一下sourceMonitor有点不知所云..
  5. vs.net2003无法打开*.xsd文件的解决方法
  6. spring之java配置(springboot推荐的配置方式)
  7. Myeclipse+mysql出现中文乱码情况
  8. 大数据架构详解_【数据如何驱动增长】(3)大数据背景下的数仓建设 amp; 数据分层架构设计...
  9. arcgis超级工具安装教程_【软件安装管家】Autodesk卸载官方工具安装教程
  10. 05丨深入浅出索引(下)
  11. 【11GR2 RAC】如何开启归档和FLASHBACK
  12. 《leetcode》best-time-to-buy-and-sell-stock-i-ii-iii
  13. 转://RMAN跨平台可传输表空间和数据库
  14. int mysql_「MYSQL」MYSQL中的int(11)到底代表什么意思?
  15. java限制符含义_JAVA的访问控制符private,default,protected,public
  16. typescript的基本结构_上帝视角看 TypeScript
  17. Android WallpaperManager 同时设置桌面壁纸与锁屏的问题
  18. reactjs前端实现文件新窗口下载
  19. P2973 [USACO10HOL]赶小猪
  20. creo6.0安装教程

热门文章

  1. 酷派7269_酷派7269手机如何Root详细教程
  2. 机动目标跟踪——目标模型概述(匀速运动CV模型)
  3. Oracle的导入导出(imp/exp,impdp/expdp)及区别
  4. Error:Cannot build artifact 'boxserver:war exploded' because it is included into a circular dependen
  5. java计算机毕业设计网络教学平台源码+数据库+系统+lw文档+mybatis+运行部署
  6. 建造者模式浅谈 与工厂模式的区别
  7. 蓝宝小企鹅双面取暖器,安全增暖,如春天般舒适
  8. Android Q 适配
  9. 密码有效性验证失败。该密码不够复杂,不符合 Windows 策略要求
  10. kaggle手机验证