ViewPager2设置smoothScroll为false仍有滚动动画,求解决方案
ViewPager2 初始化时无动画跳转中间页面的解决办法
之前碰到过一模一样的问题,给你几个亲测可行的解决办法:
1. 延迟到View布局完成后调用setCurrentItem
Activity初始化阶段,ViewPager2可能还没完成测量和布局,直接调用setCurrentItem会触发意外的滚动动画。用post把调用延后到View绘制完成后执行:
viewPager2.post { viewPager2.setCurrentItem(targetPosition, false) }
这里的targetPosition就是你要跳转的中间页面索引。
2. 反射修改内部Scroller强制无动画
如果第一种方法不生效,可以通过反射修改ViewPager2内部RecyclerView的滚动器,强制滚动时长为0:
val recyclerView = viewPager2.getChildAt(0) as RecyclerView try { // 获取RecyclerView的mViewFlinger字段 val viewFlingerField = RecyclerView::class.java.getDeclaredField("mViewFlinger") viewFlingerField.isAccessible = true val viewFlinger = viewFlingerField.get(recyclerView) // 获取ViewFlinger内部的mScroller字段 val scrollerField = viewFlinger.javaClass.getDeclaredField("mScroller") scrollerField.isAccessible = true val originalScroller = scrollerField.get(viewFlinger) as Scroller // 创建无动画的Scroller,强制滚动时长为0 val noAnimScroller = object : Scroller(viewPager2.context) { override fun startScroll(startX: Int, startY: Int, dx: Int, dy: Int, duration: Int) { super.startScroll(startX, startY, dx, dy, 0) } } // 替换Scroller,设置目标页面,再恢复原Scroller scrollerField.set(viewFlinger, noAnimScroller) viewPager2.setCurrentItem(targetPosition, false) scrollerField.set(viewFlinger, originalScroller) } catch (e: Exception) { e.printStackTrace() }
这个方法能从根源上禁用本次滚动的动画,同时不会影响后续的正常平滑滚动。
3. 确保Adapter数据提前初始化
如果你的ViewPager2使用的是FragmentStateAdapter,要保证在调用setCurrentItem之前,Adapter已经完成了数据初始化和关联。如果Adapter还没准备好,也可能导致异常的滚动动画出现。
内容的提问来源于stack exchange,提问作者Ahmet K
相关产品推荐
相关产品推荐

