在介绍Android的事件分发机制之前,我们首先要搞清楚我们分析的对象其实就是MotionEvent(点击事件),所谓Android的事件分发,其实就是MotionEvent事件的分发过程,即当一个MotionEvent产生了之后,向下分发到一个具体的View,而这个传递分发的过程就是事件的分发的过程。
具体到代码层面,分发过程其实就是三个方法来完成的:
1)public boolean dispatchTouchEvent(MotionEvent ev)
用来进行事件的分发,如果事件能够传递到当前的view,那么该方法必然会被调用,放回的结果受当前View的onTouchEvent方法和下级view的
dispatchTouchEvent方法影响,表示当前的view是否消耗事件。
2)public boolean onInterceptTouchEvent(MotionEvent ev)
用来表示是否拦截当前的事件,如果当前的View调用此方法对事件进行了拦截,那么在当前的事件的序列中该方法不会再次被调用。
3)public boolean onTouchEvent(MotionEvent ev)
在当前view的dispatchTouchEvent方法中调用,用来处理点击事件,返回的结果表示是否消耗当前的事件,如果不消耗,那么当前的View将无法再
次接受到该事件。
上诉三个方法之间的关系是什么?到底有什么区别呢?下面的一段伪代码可以清楚的描述它们的关系:
public boolean dispatchTouchEvent(MotionEvent ev) {
boolean consume=false;
if(onInterceptTouchEvent(ev)){
consume=onTouchEvent(ev);
}else{
consume=child.dispatchTouchEvent(ev)
}
return consume;
}
上诉的代码很清晰的描述了三个方法之间的关系,即对于一个ViewGroup来说,当一个事件产生了,那么ViewGroup就会调用它的dispatchTouchEvent方法,如果ViewGroup的onInterceptTouchEvent方法返回true,那么就调用onTouchEvent方法来处理该事件,如果返回false,则表示当前的View不会拦截该事件,那么该事件就会继续的朝着它的子元素分发下去,接着子View就会继续调用它的dispatchTouchEvent,如此反复下去,直到事件最终被处理。
值得我们去注意的是当一个view需要处理一个事件,如果它设置了OnTouchListener,那么OnTouchListener里面的onTouch方法会被回调,这个时候事件的处理还需要看onTouch方法的返回值,如果返回false,那么当前的View就会调用它的onTouchEvent方法,如果返回true,那么将不会调用,由此可见OnTouchListener的优先级是高于onTouchEvent的。当前的View在调用OnTouchEvent方法时,如果该View设置了OnClickListener,那么它的click方法会被调用,由此可见:我们平常使用的OnClickListener方法在事件的分发机制中优先级是处于末端的。
还有一点需要我们去注意,当一个MotionEvent产生了以后,它的传递过程遵循以下的顺序:
Activity->Window->View->子View......即Acticity接收到了点击事件之后会把事件传递给Window,Window在传递给顶级的View,顶级的View会调用dispatchTouchEvent方法开始进行事件的分发。
好啦,关于Android事件分发的机制就介绍到这里啦!