Android ViewGroup和一个View事件体系全面总结
研究的是事件序列而不是单个事件
至少要考虑到一个ViewGroup和一个View
传递或者说分发包括父View向子View传递事件(事件下发过程)和子View向父View传递事件(事件消费过程)。
另一方面,如果这个View没消费down事件,那么会一层层往上回调父View的onTouchEvent()将down事件传递给父View,所以事件的消费也是一个传递事件的过程。
上面的例子是通过编写代码验证的一个事实,至于原因,会在文中详细分析,这里只为说明需要考虑上面的几个注意点。
虽然事件体系很复杂,但是是有规律可循的,我们实践的目的就是寻找这个规律。根据我的理解,画了一张图作为Android事件机制的一个总结:
Android 事件体系全面总结+实践分
由图可以看到将整个流程分为了4种情况,下面将通过实践详细分析这4种情况,包括为什么这样划分,其他更多的情况如何归类排除等。
首先实现下图界面,界面每一层View的dispatchTouchEvent(),onInterceptTouchEvent(),onTouchEvent()三个方法中加上相应的log并返回默认的super,也可以使用这份代码:示例代码。图中,我们可以把Activity看作是顶级父View。
Android 事件体系全面总结+实践分
然后研究 Android 事件分发流程图中的4种情况:
默认情况,全部返回super,默认情况是不拦截不消费事件的。
View的onTouchEvent()消费down事件,其他默认。
ViewGroup2的onTouchEvent()消费down事件,其他默认。
ViewGroup2的onInterceptTouchEvent()拦截down之后的事件。
举例说明一下为什么要考虑上面这几点,如果事件传到了一个没有子View的View里面,这时view的onTouchEvent()会被回调,我们可以通过重写onTouchEvent()的返回值来决定是否消费这个事件。如果这个事件是down,而onTouchEvent()返回false不消费它,那么事件序列后面的事件都不再分发给这个View,如果消费了down事件,那么后续事件会继续分发给这个View,这时,如果不消费后续事件的某个move事件,那么这个move事件后面的事件依然会分发给这个View。
由此可见,对事件序列里某个事件的消费情况是会影响后续事件的分发的。