先放张流程图,本文的所有内容都基于这张图,如下:
讲解Android事件分发的文章很多了,这里我是在理解之后,做的一个总结。按照事件传递的流程,把每一步的事件处理和返回结果做个梳理,这里的总结只包含了ACTION_DOWN事件。
1
先看Activity的
分析上述代码:首先事件交给Activity所附属的Window进行分发,我们进入getWindow().superDispatchTouchEvent(ev)
这段代码:
分析代码可以看出,PhoneWindow将事件传递给了DecorView,也就是最顶级的View,它继承自FrameLayout,所以它是一个ViewGroup,这样事件的分发,就从Activity进入了ViewGroup。这里我们先只讨论Activity对分发事件结果的处理。
1)如果返回true,则说明该事件被消费,则终止传递。
2)如果返回false,意味着事件没人处理,所有View的onTouchEvent都返回了false,那么Activity的onTouchEvent就会调用。
我们接着往下看,当事件传递给ViewGroup的dispatchTouchEvent()
,它是如何处理的。
2
|
|
这段代码比较多了,其实我也看不下去……,所以这里我直接结合流程图,给出结论吧:
1)ViewGroup的dispatchTouchEvent()
方法,如果其OnTouchListener没有被设置,则默认会去调用它的onInterceptTouchEvent()
方法。如果设置了OnTouchListener,则会屏蔽掉onTouchEvent事件。(关于OnTouchListener和OnTouchEvent会在文末讲解)
2)如果返回结果为true,说明事件自行消费,例如设置了OnTouchListener,则终止传递。
3)返回false意味着事件没人处理,则回溯给Activity的onTouchEvent进行处理。
3
下面进入ViewGroup的onInterceptTouchEvent()
方法:
只有ViewGroup中有此方法,View中没有。它的作用时判断“是否拦截事件”。
1)默认情况是返回false,也就是不拦截,并将事件传递给子View的dispatchTouchEvent()
。
2)返回true意味着拦截此事件,并将事件分发给自己的onTouchEvent。
4
下面进入ViewGroup的onTouchEvent()
方法:
1)返回true,说明消费该事件,传递终止。
2)返回false,意味着不消费该事件,将事件传递给子View的dispatchTouchEvent()
进行分发。
5
View没有interceptTouchEvent()方法,因为它下面已经没有View了,不需要进行拦截。
1)与ViewGroup的此方法一样,如果自己不消费,默认情况下是传递给该View的onTouchEvent
进行事件处理。
2)返回true,说明被自己消费,终止传递。
3)返回false说明该View不进行处理,回溯给父View的onTouchEvent()
方法。
6
如果View能接受到事件,那么它的onTouchEvent()
方法将是最后被调用的,它的事件处理规则与ViewGroup的是一样的:
1)返回true,说明自行处理,传递结束。
2)返回false,意味着不处理该事件,回溯给上一级View的onTouchEvent()
方法处理。
onTouchEvent、onTouchListener、onClickListener
在区别这三者之前,先上一张View的dispatchTouchEvent()
的内部执行逻辑流程图,图片来自谷哥的小弟:
1、onTouchEvent
与onTouchListener
都是处理Touch事件的API。不同的是,onTouchEvent
是Android系统自身对于Touch事件处理的一个实现,onTouchListener
是View暴露给用户的接口,方便用户处理Touch事件。
onTouchListener
的优先级高于onTouchEvent
,如果onTouchListene
r被调用,且返回true,则onTouchEvent
不会被执行,如果返回false,onTouchEvent
则会被执行。
2、onClickListener
是在ACTIN_UP之后才会被调用,它是这三者中最后一个被调用的。