原创首发
如何降低 ViewPager2 小部件的滚动敏感度

缘起
当你打开官网中 ViewPager 的文档 时,你会发现这么一句描述:”Display Views or Fragments in a swipeable format. If possible, use viewpager2 instead.“ (译:以可滑动的形式显示 Views 或 Fragments。如果可能的话,使用 ViewPager2 代替。)。
没错,官方推荐我们使用 ViewPager2 !
Tips:我使用的 ViewPager2 版本
implementation "androidx.viewpager2:viewpager2:1.0.0"
ViewPager2 简介
先说说什么是 ViewPager2 吧,引用一下官网对 ViewPager2 的介绍:
Display Views or Fragments in a swipeable format.
翻译:”以可滑动的形式显示 Views 或 Fragments。“
缘因
有时你使用 ViewPager2 有复杂的嵌套布局。在水平滚动的 ViewPager2 中使用了 Fragment 作为容器,并且在 Fragment 内部使用垂直滚动的 RecyclerView 作为列表显示时,你会惊奇的发现,它竟然没有和 ViewPager 一样显得不那么灵敏,相反而言它表现得非常灵敏,因为它无法正确区分水平判断和垂直的临界条件。
缘灭
我们的解决方案十分简单粗暴 —— 使用反射修改它的 ”TouchSlop“ 值 ,让它显得不再那么过于灵敏。
Kotlin 扩展函数
fun ViewPager2.reduceDragSensitivity() {
val recyclerViewField = ViewPager2::class.java.getDeclaredField("mRecyclerView")
recyclerViewField.isAccessible = true
val recyclerView = recyclerViewField.get(this) as RecyclerView
val touchSlopField = RecyclerView::class.java.getDeclaredField("mTouchSlop")
touchSlopField.isAccessible = true
val touchSlop = touchSlopField.get(recyclerView) as Int
touchSlopField.set(recyclerView, touchSlop * 2) // "2" was obtained experimentally
}
Java 工具类方法
public static void reduceDragSensitivity(ViewPager2 viewPager2) {
try {
Field recyclerViewField = ViewPager2.class.getDeclaredField("mRecyclerView");
recyclerViewField.setAccessible(true);
RecyclerView recyclerView = (RecyclerView) recyclerViewField.get(viewPager2);
Field touchSlopField = RecyclerView.class.getDeclaredField("mTouchSlop");
touchSlopField.setAccessible(true);
int touchSlop = (int) touchSlopField.get(recyclerView);
touchSlopField.set(recyclerView, touchSlop * 2); // "2" was obtained experimentally
} catch (NoSuchFieldException | IllegalAccessException e) {
e.printStackTrace();
}
}
参考链接
本文由
A lonely cat
原创发布于
阳光沙滩
,未经作者授权,禁止转载