10

有谁知道如何修改 ViewPager 的灵敏度?

目前我使用来自 android v4 支持库的 ViewPager 来实现我自己的照片查看器。

但是,默认的 ViewPager 太敏感了,当我的手指在屏幕上触摸并移动很短的距离(可能只有 0.5 厘米)时。然后 ViewPager 将切换到滚动到下一张/上一张照片视图。

有没有办法覆盖 ViewPager 的默认行为以降低灵敏度?

感谢任何回应。

4

4 回答 4

6

使用反射ViewPager2提取和增加。mTouchSlop

    private 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*8)       // "8" was obtained experimentally
    }

从您的视图寻呼机调用此函数

val viewPager: ViewPager2 = view.findViewById(R.id.pager)
viewPager.reduceDragSensitivity()

爪哇版

private void reduceDragSensitivity() {
    try {
        Field ff = ViewPager2.class.getDeclaredField("mRecyclerView") ;
        ff.setAccessible(true);
        RecyclerView recyclerView =  (RecyclerView) ff.get(viewPager);
        Field touchSlopField = RecyclerView.class.getDeclaredField("mTouchSlop") ;
        touchSlopField.setAccessible(true);
        int touchSlop = (int) touchSlopField.get(recyclerView);
        touchSlopField.set(recyclerView,touchSlop*4);
    } catch (NoSuchFieldException e) {
        e.printStackTrace();
    } catch (IllegalAccessException e) {
        e.printStackTrace();
    }
}

所有功劳均归功于Alexander ShevelevMahmoud Shabat

于 2020-08-17T17:11:26.300 回答
5

我已经从兼容性库的 src 中检查了 ViewPager.java,似乎没有办法通过 xml 或一些 setter 来做到这一点。ViewPager 的代码如下:

final float density = context.getResources().getDisplayMetrics().density;
mFlingDistance = (int) (MIN_DISTANCE_FOR_FLING * density);
mCloseEnough = (int) (CLOSE_ENOUGH * density);
mDefaultGutterSize = (int) (DEFAULT_GUTTER_SIZE * density);

如您所见,它使用它的内部常数来确定投掷距离等。

好消息是:您可以将 ViewPager(此处应考虑其许可)复制到您的代码中并对其进行扩展,例如从 xml 属性中获取弹射距离。

于 2012-08-27T03:02:23.903 回答
3

您可以像这样反映 mFlingDistance 字段:

Field mFlingDistance;
mFlingDistance = ViewPager.class.getDeclaredField("mFlingDistance");
mFlingDistance.setAccessible(true);

// Set custom value:
mFlingDistance.set(mPager, 30);
于 2016-04-04T20:45:25.333 回答
1

虽然 Pethő Jonatán 有一个很好的指针来获得更好的灵敏度,但除了投掷距离之外,您可能还需要降低 minimumVelocity。

您可能希望在 onCreate 中初始化 viewpager 后执行此操作:

 viewPager = findViewById(R.id.viewPager);
 Field mFlingDistance;
 Field mMinimumVelocity;

 try {
     mFlingDistance=ViewPager.class.getDeclaredField("mFlingDistance");
     mMinimumVelocity=ViewPager.class.getDeclaredField("mMinimumVelocity");

     mFlingDistance.setAccessible(true);
     mMinimumVelocity.setAccessible(true);

     //customize the values
     mFlingDistance.set(viewPager, 10);
     mMinimumVelocity.set(viewPager, 400);
    } catch (Exception e) {
      e.printStackTrace();
    }
于 2020-05-10T06:11:00.787 回答