Android事件传递解析(下)
上篇文章 Android事件传递解析(上) 解析了有关事件传递在默认情况(返回super,OnTouch返回false)下的事件传递流程,接下来我们来看看各个控件拦截事件后,事件的分发流程
拦截后的事件传递流程
我将每个事件拦截掉,然后观察打印的log,事件传递的流程如下所示
可以看出
- 在activity的dispatchTouchEvent中返回true或false,该事件被消费,不会向下传递。
- 在ViewGroup和View的dispatchTouchEvent,onTouch和onTouchEvent中返回true,事件被消费,不会继续传递。
- 在ViewGroup和View的dispatchTouchEvent中返回false该事件不再向下传递,转回上层进行处理。
- View的onTouchEvent中返回super或true,DOWN事件终止,其中返回true后View的onClick事件不再执行。
onInterceptTouchEvent拦截事件
这里着重说一下onInterceptTouchEvent方法,父控件如果要拦截该事件,就要在onInterceptTouchEvent方法中返回true或者super,而子View如果需要禁止onInterceptTouchEvent方法,可以在其onTouch事件的ACTION_DOWN事件中调用
v.getParent().requestDisallowInterceptTouchEvent(true);
来禁止父控件拦截事件,这个方法在处理View间滑动冲突的时候非常重要。
ACTION_MOVE和ACTION_UP事件
- 在dispatchTouchEvent中返回true拦截事件后,MOVE和UP事件与DOWN事件的走向一致
- 在ViewGroup的onInterceptTouchEvent中拦截事件,事件只交给上层处理而不在本层的onTouch和onTouchEvent事件中处理
- 在View的OnTouchEvent中返回false,ACTION_MOVE和ACTION_UP事件交由上层ViewGroup处理,返回super和true的处理流程与ACTION_DOWN一致。在ViewGroup的onTouchEvent中返回true,则ACTION_MOVE和ACTION_UP事件仅在本层处理并消费掉。
- 在View接收到ACTION_DOWN和ACTION_UP事件后才会触发onclick事件
总结
- 在某个控件消费了这个触摸事件后,ACTION_MOVE和ACTION_DOWN事件是不会向下传递的。
- 一般情况下,我们不应该在dispatchTouchEvent中去拦截事件,如果有拦截需求,一般会在onInterceptTouchEvent中去处理。
- 在View的OnTouch事件中返回true表示事件被消费,不会向下传递,默认返回false不拦截事件
参考文章: