View的事件机制
为什么会有事件分发机制?
安卓上面的View是树形结构的,View可能会重叠在一起,当我们点击的地方有多个View都可以响应的时候,这个点击事件应该给谁呢?为了解决这个问题,就有了事件分发机制。
三个重要的事件分发的方法
despatchTouchEvent
对于dispatchTouchEvent返回false的含义应该是:事件停止往子view传递和分发,同时开始往父控件回溯(父控件的onTouchEvent开始从下往上回传直到某个onTouchEvent return ture),事件分发机制就像递归,return false的意思就是递归停止然后回溯。
onInterceptTouchEvent
决定是否拦截事件,拦截的话就不在分发
onTouchEvent
对于onTouchEvent return false,就是不消费事件,并让事件继续往父控件的方向从下往上流动。相当于员工处理不了这个事件,就返回false,然后让上司处理,如果上司不行返回false,就让上司的上司处理。
三个方法的关系
伪代码
public boolean dispatchTouchEvent(MotionEvent ev){
boolean cosume=false;
if(onInterceptTouchEvent(ev)){
consume = onTouchEvent(en);
}else{
consume = chile.dispatchTouchEvent(ev);
}
return consume;
}
大概流程就是:对于一个跟ViewGroup来说,点击事件产生后,首先会传递给它,这时他的dispatchTouchEvent就会被调用,如果这个ViewGroup的onInterceptTouchEvent方法返回true就表示它要拦截当前事件,接着整个事件就会交给ViewGroup处理,即它的onTouchEvent方法就会被调用:如果这个onInterceptTouchEvent不拦截,这时当前事件就会继续传递给它的子元素,接着子元素的dispatchTouchEvent方法就会被调用,如此反复直到事件被最终处理
注意:
当以个View需要处理事件时,如果它设置了OnTouchListenner,那么OnTouchListenner中的onTouch方法会被回调,这时事件如果处理还要看onTouch的返回值,如果返回FALSE,则当前View的onTouchEnvent方法会被调用;如果返回true,那么onTouchEvent将不会被调用。由此可见,给View设置的OnTouchListenner,其优先级比onTouchEnvent要高。
事件分发流程
这个流程最好是用图的方式说明
Activity -> PhoneWindow -> DecorView -> ViewGroup -> --- ->View
图一这个是从源码的角度画的,画出的情况没有图二多:
图二这个好理解:
方框里的true就是事件被消费,默认的super或者部分FALSE就是保证事件“U”传递
这两幅图看起来有所区别,但并不矛盾,只是说明的角度不同,图二要本质化,全面一点