如何降低 ViewPager2 小部件的滚动敏感度

缘起

当你打开官网中 ViewPager 的文档 时,你会发现这么一句描述:”Display Views or Fragments in a swipeable format. If possible, use viewpager2 instead.“ (译:以可滑动的形式显示 Views 或 Fragments。如果可能的话,使用 ViewPager2 代替。)。


没错,官方推荐我们使用 ViewPager2 !


Tips:我使用的 ViewPager2 版本

1
implementation "androidx.viewpager2:viewpager2:1.0.0"

ViewPager2 简介

先说说什么是 ViewPager2 吧,引用一下官网对 ViewPager2 的介绍:

Display Views or Fragments in a swipeable format.

翻译:”以可滑动的形式显示 Views 或 Fragments。“

ViewPager2 官方文档


缘因

有时你使用 ViewPager2 有复杂的嵌套布局。在水平滚动的 ViewPager2 中使用了 Fragment 作为容器,并且在 Fragment 内部使用垂直滚动的 RecyclerView 作为列表显示时,你会惊奇的发现,它竟然没有和 ViewPager 一样显得不那么灵敏,相反而言它表现得非常灵敏,因为它无法正确区分水平判断和垂直的临界条件。


缘灭

我们的解决方案十分简单粗暴 —— 使用反射修改它的 ”TouchSlop“ 值 ,让它显得不再那么过于灵敏。


Kotlin 扩展函数

1
2
3
4
5
6
7
8
9
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 工具类方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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();
}
}

参考链接

ViewPager

ViewPager2

How to reduce scroll sensitivity of ViewPager2 widget


如何降低 ViewPager2 小部件的滚动敏感度
https://blog.funkt.cn/2022/05/14/1525711636801785858/
作者
anjiemo
发布于
2022年5月15日
许可协议
未经作者授权,禁止转载