为什么即使在自定义 OnTouchListener 实现后 RecyclerView 仍然滚动?

Why RecyclerView still scrolls even after custom OnTouchListener implemented?

我知道这可能是一个愚蠢的问题,但我需要在实施此代码后知道:

recyclerView.setOnTouchListener(new View.OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            return false;
        }
    });

为什么 recyclerViewlistener return 的 false 时仍在滚动?或者更确切地说,滚动行为是在哪里处理和处理的?

我知道 return true 表示触摸事件被消耗,false 表示触摸事件应该传递到视图层次结构中的下一个 view。在我看来(这可能是错误的),return 类型不应该改变 view 行为。因为当你不处理 onTouchListener 时,这意味着没有触摸事件(包括滚动行为)被处理,所以 recyclerView 不应该滚动,无论 return 类型是 truefalse。我的看法有什么问题?我希望我已经足够清楚了。

I know that return true means the touch event is consumed and false means the touch event should get passed to the next view in view hierarchy

这不是真的,View 处理触摸事件时的正确顺序是:

  • View.dispatchTouchEvent()会先被调用

  • 如果退出

    ,则将事件发送到View.OnTouchListener.onTouch()
  • 如果没有消耗,处理View.onTouchEvent()

在你的例子中因为你的 return false in View.OnTouchListener.onTouch(),这意味着你没有消费事件,所以事件将被路由到 View.onTouchEvent() of RecyclerView,这解释了为什么 RecyclerView 仍在滚动。

解决方案 1

Return true in View.onTouchListener.onTouch() 表明 RecyclerView 将消耗所有触摸事件。

recyclerView.setOnTouchListener(new View.OnTouchListener() {
    @Override
    public boolean onTouch(View v, MotionEvent event) {
        // I will consume all touch events,
        // so View.onTouchEvent() will not be called.
        return true;
    }
});

解决方案 2

创建一个从 RecyclerView 和 return false 延伸到 View.onTouchEvent() 的子 class 以表明 RecyclerView 不对任何触摸事件都不感兴趣。

public class MyRecyclerView extends RecyclerView {

    public MyRecyclerView(@NonNull Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    public boolean onTouchEvent(MotionEvent e) {
        // I don't show interested in any touch event.
        return false;
    }
}

This 是关于 Android 触摸系统的精彩介绍,你应该看看。