为什么滑动ListView时不响应点击事件

时间:2022-08-14 19:36:24

为什么滑动ListView时不响应点击事件

从onInterceptTouchEvent方法说起,该方法是Viewgroup中的方法,默认实现直接返回false。

在dispatchTouchEvent函数分发事件时,首先要问一下onInterceptTouchEvent对该事件是否有兴趣。
如果Viewgroup对该事件感兴趣,会在onInterceptTouchEvent中返回true,截断事件向下传递。

下面分别对ACTION_DOWN,ACTION_MOVE,ACTION_UP三类事件发生时,onInterceptTouchEvent是否介入进行讨论

一、当ACTION_DOWN事件发生时,如果onInterceptTouchEvent返回true**
表示Viewgroup要接管控制权,由Viewgroup的onTouchEvent响应事件,后续的ACTION_MOVE,ACTION_UP事件都会由Viewgroup的onTouchEvent处理。
如果onInterceptTouchEvent返回false, 事件将由Viewgroup的某个子控件处理。

二、在ACTION_DOWN事件发生时,onInterceptTouchEvent返回false,在ACTION_MOVE事件发生时返回true
Viewgroup会强制介入,阻断消息向子控件传递(子控件已经处理了ACTION_DOWN事件)。ACTION_MOVE事件交由Viewgroup的onTouchEvent处理。同时向目标控件(处理ACTION_DOWN的子控件)传递一个ACTION_CANCEL事件,意思是说后续的事件将由我处理,你就歇着去吧。
注意只有当onInterceptTouchEvent在ACTION_DOWN事件返回false时,代码才会执行到这里。
这种情况其实比较常见,举个例子。
在滑动listview时,虽然也执行了点击操作但listeview只会响应滑动操作,不会处理点击事件。

如何实现的:

1、listview中的item对事件的处理操作肯定是在ACTION_UP中进行的。
2、如果在onInterceptTouchEvent中判断用户的操作达到了滑动的条件,在onInterceptTouchEvent返回true,截断事件向下传递。后续事件将由Listview处理。在item中接收不到ACTION_UP事件,也就不会触发点击操作。
3、可以参考AbsListView中onInterceptTouchEvent的代码。

三、在MotionEvent.ACTION_UP发生时,onInterceptTouchEvent还有一次插手的机会,这种情况应该比较少见。
已经生米煮成熟饭了,这时介入估计已经晚了。