描述一下Android的事件分发机制?
Android事件分发机制的本质:事件从哪个对象发出,经过哪些对象,最终由哪个对象处理了该事件。此处对象指的是Activity、Window与View。
Android事件的分发顺序:Activity(Window) -> ViewGroup -> View
事件来临------
Activity询问Window是否能处理------
Window询问DecorView是否能处理------
DecorView查看自己的onInterceptTouchEvent返回值 ture则处理(完),否则返回False------
DecorView遍历自己的子View,询问其中的RelativeLayout是否能处理------
RelativeLayout没有拦截事件,继续遍历自己的子View------
发现事件发生在TexView上,询问TextView是否能处理------
TextView查看自己,发现无法消耗,告诉RelativeLayout消耗不了------
RelativeLayout看TextView消耗不了,想自己消耗,结果一看自己的onTouchEvent也无法消耗------
RelativeLayout告诉DecorView事件无法消耗------
DecorView查看自己,也无法消耗------
DecorView告诉Window无法消耗------
Window告诉Activity无法消耗------
Activity自己来处理,调用自己的onTouchEvent,发现自己还是消耗不了------
算了,不处理了!
通俗语言来讲:,事件来的时候,Activity会询问Window,Window这个事件你能不能消耗,Window一看,你先等等,我去问问DecorView他能不能消耗,DecorView一看,onInterceptTouchEvent返回false啊,不让我拦截啊,遍历一下子View吧,问问他们能不能消耗,那个谁,事件按在你的身上了,你看看你能不能消耗,RelativeLayout一看,也没有让我拦截啊,我也得遍历看看这个事件发生在那个子View上面,那个TextView,事件在你身上,你能不能消耗了他。TextView一看,消耗不了啊,RelativeLayout一看TextView消耗不了啊,mFirstTouchTarget==null啊,得,我自己消耗吧,嗯!一看自己的onTouchEvent也消耗不了啊!那个DecorView事件我消耗不了,DecorView一看自己,我也消耗不了,继续往上传,那个Window啊。事件我消耗不了啊,Window再告诉Activity事件消耗不了啊。Activity还得我自己来啊。调用自己的onTouchEvent,还是消耗不了,算了,不要了。
Android事件的分发主要由三个方法来完成,如下所示:
// 父View调用dispatchTouchEvent()开始分发事件
public boolean dispatchTouchEvent(MotionEvent event){
boolean consume = false;
// 父View决定是否拦截事件
if(onInterceptTouchEvent(event)){
// 父View调用onTouchEvent(event)消费事件,如果该方法返回true,表示
// 该View消费了该事件,后续该事件序列的事件(Down、Move、Up)将不会在传递
// 该其他View。
consume = onTouchEvent(event);
}else{
// 调用子View的dispatchTouchEvent(event)方法继续分发事件
consume = child.dispatchTouchEvent(event);
}
return consume;
}