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

Posted

技术标签:

【中文标题】为啥即使在自定义 OnTouchListener 实现后 RecyclerView 仍然滚动?【英文标题】:Why RecyclerView still scrolls even after custom OnTouchListener implemented?为什么即使在自定义 OnTouchListener 实现后 RecyclerView 仍然滚动? 【发布时间】:2021-03-29 05:06:15 【问题描述】:

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

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

为什么listener 返回falserecyclerView 仍在滚动?或者更确切地说,滚动行为在哪里处理和处理?

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

【问题讨论】:

【参考方案1】:

我知道 return true 意味着触摸事件被消耗, false 意味着触摸事件应该被传递到视图层次结构中的下一个视图

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

View.dispatchTouchEvent() 将首先被调用

如果退出,则将事件发送到View.OnTouchListener.onTouch()

如果没有消费,则处理View.onTouchEvent()

在您的情况下,因为您在View.OnTouchListener.onTouch() 中返回false,这意味着您不消费该事件,因此该事件将被路由到RecyclerViewView.onTouchEvent(),这就解释了为什么RecyclerView 仍然存在滚动。

解决方案 1

View.onTouchListener.onTouch() 中返回true 以表明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 扩展的子类,并在View.onTouchEvent() 中返回false,以表明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 触控系统的精彩介绍,您应该看看。

【讨论】:

以上是关于为啥即使在自定义 OnTouchListener 实现后 RecyclerView 仍然滚动?的主要内容,如果未能解决你的问题,请参考以下文章

为啥我必须在自定义 NIB / XIB 中连接 IBOutlet 两次?

为啥我不能在自定义字段验证器中返回全局消息键?

iOS:为啥在自定义 TableViewCell 中写入此文本字段的文本似乎不可读

为啥在自定义 WinRT C++/CX 控件中默认添加 [Windows::Foundation::Metadata::WebHostHidden]?

为啥我在自定义单元格中的复选框在快速选择和滚动时显示不同的行为?

为啥我裁剪的图像很小?