当内部视图的onTouch事件发生时,如何防止ViewPager2被滑动

11

我有一个包含片段的ViewPager2。

在该片段中,我有一个带有特定触摸逻辑的自定义视图,需要涉及手指移动。

当内部视图截取触摸事件时,我应如何防止ViewPager滑动?

override fun onTouchEvent(event: MotionEvent?): Boolean {
    if (event?.action == MotionEvent.ACTION_DOWN || event?.action == MotionEvent.ACTION_MOVE) {
       //Do some stuff here
    }
    return true
}

在滑动此视图时,视图页面仍会滑动到其他页面。

3个回答

8

为内部视图设置 OnTouchListener。在 onTouch() 方法中调用:

viewPager.requestDisallowInterceptTouchEvent(true)
在其onInterceptTouchEvent()方法中处理滑动操作。以上代码会避免ViewPager调用onInterceptTouchEvent()。当你滑动时,ViewPager会在onInterceptTouchEvent()方法中返回true,这也会阻止触摸事件传递给子视图。因此,禁止拦截允许子视图处理触摸事件。

当内部视图没有被触摸时,应将其设置回false

根据我的经验,onInterceptTouchEvent()会阻止onTouchEvent()方法的执行,但不会阻止OnTouchListener的执行。所以关键是为内部视图设置OnTouchListener


1
尝试使用这个解决方案停止自动滑动的计时器,它有效。 - HUAN XIE

3
为了解决这个问题,你应该像这样扩展ViewPager2:
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 * 6) // "6" was obtained experimentally
}

并调用 reduceDragSensitivity 函数。这样,ViewPager2 将会如下所示:

view_pager.reduceDragSensitivity()

Example: https://github.com/ali-sardari/ViewPager2Example

enter image description here


1
以下内容对我很有帮助,适用于自定义视图类(可纵向和横向滚动)。 包含此自定义视图的ViewPager2会获取所有水平移动并将其转换为页面更改。 在创建GestureDetector期间调用requestDisallowInterceptTouchEvent,可以使自定义视图中的“常规”滚动保持不变,但仍然可以在ViewPager2中使用fling手势。 当然,您的情况可能会有所不同。 我没有在任何地方将标志改回false; 这似乎在OnTouchUp中处理。
    /* Called during view construction */
private void addGestureDetection(Context context) {
    mGestureDetector = new GestureDetector(context, new SimpleOnGestureListener() {

        @Override
        public boolean onScroll (MotionEvent e1,
                                 MotionEvent e2,
                                 float distanceX,
                                 float distanceY)
        {
            /* Prevent the ViewPager2 from grabbing all the scroll events and turning
            a horizontal scroll into a view change.  The ViewPager2 still gets flings gestures*/
            getParent().requestDisallowInterceptTouchEvent(true);

            ...
        }
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接