读《Android群英传》笔记–事件拦截机制分析
2017/6/29 星期四 下午 8:36:41
Android的View结构是树形结构,也就是说,View可以放在ViewGroup里面,通过不同的组合来实现不同样式。那么问题就是,View放在一个ViewGroup里面,这个ViewGroup又放在另外一个ViewGroup里面,甚至还可能继续嵌套,一层一层的叠加起来。可是,触摸事件就一个,对于同一个事件,子View和父ViewGroup都有可能想要进行处理,这样就很有必要对事件拦截机制进行分析。
1、对于事件拦截机制分析,主要设置三个方法:
- 事件分发
- 事件拦截
事件处理
//事件分发 @Override public boolean dispatchTouchEvent(MotionEvent ev) { // TODO Auto-generated method stub return super.dispatchTouchEvent(ev); } //事件拦截:true,拦截,不继续;false,不拦截,继续流程;默认false @Override public boolean onInterceptTouchEvent(MotionEvent ev) { // TODO Auto-generated method stub return super.onInterceptTouchEvent(ev); } //事件处理:true,不进行传递给上一级ViewGroup;false,报告给上一级父控件;默认false @Override public boolean onTouchEvent(MotionEvent event) { // TODO Auto-generated method stub return super.onTouchEvent(event); }
2、运行流程
如果ViewGroupA 包含 ViewGroupB,而ViewGroupB 包含一个子View。如下图所示:
(1)第一种情况:事件分发,事件拦截和事件处理都是默认false,不进行处理。
运行的流程大致是:
ViewGroupA dispatchTouchEvent -->
ViewGroupA onInterceptTouchEvent -->
ViewGroupB dispatchTouchEvent -->
ViewGroupB onInterceptTouchEvent -->
View dispatchTouchEvent -->
View onTouchEvent -->
ViewGroupB onTouchEvent -->
ViewGroupA onTouchEvent
(2)第二种情况:把ViewGroupA 的onInterceptTouchEvent()的方法返回值改为true,其他默认;
运行的流程大致是:
ViewGroupA dispatchTouchEvent -->
ViewGroupA onInterceptTouchEvent -->
ViewGroupA onTouchEvent
从上述流程可以看到,ViewGroupA直接把事件拦截掉了,不让它所包含的 子ViewGroupB 和 子View 进行事件处理,直接自己(ViewGroupA)的onTouchEvent()事件就处理了。
(3)第三种情况:把ViewGroupB 的onInterceptTouchEvent()的方法返回值改为true,其他默认;
运行的流程大致是:
ViewGroupA dispatchTouchEvent -->
ViewGroupA onInterceptTouchEvent -->
ViewGroupB dispatchTouchEvent -->
ViewGroupB onInterceptTouchEvent -->
ViewGroupB onTouchEvent -->
ViewGroupA onTouchEvent
从上述流程来看,ViewGroupB把事件拦截下来了,不让 子View 进行事件处理,自己(ViewGroupB)处理掉了,然后把处理报告给 父ViewGroupA 处理了。
(4)第四种情况:把 子View 的onTouchEvent()直接返回true,其他的默认。
运行的流程大致是:
ViewGroupA dispatchTouchEvent -->
ViewGroupA onInterceptTouchEvent -->
ViewGroupB dispatchTouchEvent -->
ViewGroupB onInterceptTouchEvent -->
View dispatchTouchEvent -->
View onTouchEvent
从上述流程可以来看,进行到 子View 处理事件,就不再上报到 父ViewGroupB 和 祖父ViewGroupA处理了。
(5)第五种情况:把 子ViewGroupB 的onTouchEvent()直接返回true,其他的默认。
ViewGroupA dispatchTouchEvent -->
ViewGroupA onInterceptTouchEvent -->
ViewGroupB dispatchTouchEvent -->
ViewGroupB onInterceptTouchEvent -->
View dispatchTouchEvent -->
View onTouchEvent -->
ViewGroupB onTouchEvent
从上述流程来看,ViewGroupB 处理完事件后不再上报给 父ViewGroupA 再去处理了。