图解Android事件分发机制Word下载.docx
- 文档编号:21426823
- 上传时间:2023-01-30
- 格式:DOCX
- 页数:16
- 大小:1.50MB
图解Android事件分发机制Word下载.docx
《图解Android事件分发机制Word下载.docx》由会员分享,可在线阅读,更多相关《图解Android事件分发机制Word下载.docx(16页珍藏版)》请在冰豆网上搜索。
注:
∙仔细看的话,图分为3层,从上往下依次是Activity、ViewGroup、View
∙事件从左上角那个白色箭头开始,由Activity的dispatchTouchEvent做分发
∙箭头的上面字代表方法返回值,(returntrue、returnfalse、returnsuper.xxxxx(),super的意思是调用父类实现。
∙dispatchTouchEvent和onTouchEvent的框里有个【true—->
消费】的字,表示的意思是如果方法返回true,那么代表事件就此消费,不会继续往别的地方传了,事件终止。
∙目前所有的图的事件是针对ACTION_DOWN的,对于ACTION_MOVE和ACTION_UP我们最后做分析。
∙Activity的dispatchTouchEvent无论返回什么,都会调用ViewGroup的dispatchTouchEvent(自行看源码)
仔细看整个图,我们得出事件流走向的几个结论(希望读者专心的看下图1,多看几遍,脑子有比较清晰的概念。
)
1、如果事件不被中断,整个事件流向是一个类U型图,我们来看下这张图,可能更能理解U型图的意思。
图2.
所以如果我们没有对控件里面的方法进行重写或更改返回值,而直接用super调用父类的默认实现,那么整个事件流向应该是从Activity—->
ViewGroup—>
View从上往下调用dispatchTouchEvent方法,一直到叶子节点(View)的时候,再由View—>
Activity从下往上调用onTouchEvent方法。
2、dispatchTouchEvent和onTouchEvent一旦returntrue,事件就停止传递了(到达终点)(没有谁能再收到这个事件)。
看下图中只要returntrue事件就没再继续传下去了,对于returntrue我们经常说事件被消费了,消费了的意思就是事件走到这里就是终点,不会往下传,没有谁能再收到这个事件了。
图3.
3、dispatchTouchEvent和onTouchEventreturnfalse的时候事件都回传给父控件的onTouchEvent处理。
图4.
看上图深蓝色的线,对于返回false的情况,事件都是传给父控件onTouchEvent处理。
∙对于dispatchTouchEvent返回false的含义应该是:
事件停止往子View传递和分发同时开始往父控件回溯(父控件的onTouchEvent开始从下往上回传直到某个onTouchEventreturntrue),事件分发机制就像递归,returnfalse的意义就是递归停止然后开始回溯。
∙对于onTouchEventreturnfalse就比较简单了,它就是不消费事件,并让事件继续往父控件的方向从下往上流动。
4、dispatchTouchEvent、onTouchEvent、onInterceptTouchEvent
ViewGroup和View的这些方法的默认实现就是会让整个事件安装U型完整走完,所以returnsuper.xxxxxx()就会让事件依照U型的方向的完整走完整个事件流动路径),中间不做任何改动,不回溯、不终止,每个环节都走到。
Paste_Image.png
所以如果看到方法returnsuper.xxxxx()那么事件的下一个流向就是走U型下一个目标,稍微记住上面这张图,你就能很快判断出下一个走向是哪个控件的哪个函数。
5、onInterceptTouchEvent的作用
图5.
Intercept的意思就拦截,每个ViewGroup每次在做分发的时候,问一问拦截器要不要拦截(也就是问问自己这个事件要不要自己来处理)如果要自己处理那就在onInterceptTouchEvent方法中returntrue就会交给自己的onTouchEvent的处理,如果不拦截就是继续往子控件往下传。
默认是不会去拦截的,因为子View也需要这个事件,所以onInterceptTouchEvent拦截器returnsuper.onInterceptTouchEvent()和returnfalse是一样的,是不会拦截的,事件会继续往子View的dispatchTouchEvent传递。
6、ViewGroup和View的dispatchTouchEvent方法返回super.dispatchTouchEvent()的时候事件流走向。
图6
首先看下ViewGroup的dispatchTouchEvent,之前说的returntrue是终结传递。
returnfalse是回溯到父View的onTouchEvent,然后ViewGroup怎样通过dispatchTouchEvent方法能把事件分发到自己的onTouchEvent处理呢,returntrue和false都不行,那么只能通过Interceptor把事件拦截下来给自己的onTouchEvent,所以ViewGroupdispatchTouchEvent方法的super默认实现就是去调用onInterceptTouchEvent,记住这一点。
那么对于View的dispatchTouchEventreturnsuper.dispatchTouchEvent()的时候呢事件会传到哪里呢,很遗憾View没有拦截器。
但是同样的道理returntrue是终结。
returnfalse是回溯会父类的onTouchEvent,怎样把事件分发给自己的onTouchEvent处理呢,那只能returnsuper.dispatchTouchEvent,View类的dispatchTouchEvent()方法默认实现就是能帮你调用View自己的onTouchEvent方法的。
说了这么多,不知道有说清楚没有,我这边最后总结一下:
∙对于dispatchTouchEvent,onTouchEvent,returntrue是终结事件传递。
returnfalse是回溯到父View的onTouchEvent方法。
∙ViewGroup想把自己分发给自己的onTouchEvent,需要拦截器onInterceptTouchEvent方法returntrue把事件拦截下来。
∙ViewGroup的拦截器onInterceptTouchEvent默认是不拦截的,所以returnsuper.onInterceptTouchEvent()=returnfalse;
∙View没有拦截器,为了让View可以把事件分发给自己的onTouchEvent,View的dispatchTouchEvent默认实现(super)就是把事件分发给自己的onTouchEvent。
ViewGroup和View的dispatchTouchEvent是做事件分发,那么这个事件可能分发出去的四个目标
——>
后面代表事件目标需要怎么做。
1、自己消费,终结传递。
——->
returntrue;
2、给自己的onTouchEvent处理——->
调用super.dispatchTouchEvent()系统默认会去调用onInterceptTouchEvent,在onInterceptTouchEventreturntrue就会去把事件分给自己的onTouchEvent处理。
3、传给子View——>
调用super.dispatchTouchEvent()默认实现会去调用onInterceptTouchEvent在onInterceptTouchEventreturnfalse,就会把事件传给子类。
4、不传给子View,事件终止往下传递,事件开始回溯,从父View的onTouchEvent开始事件从下到上回归执行每个控件的onTouchEvent——->
returnfalse;
由于View没有子View所以不需要onInterceptTouchEvent来控件是否把事件传递给子View还是拦截,所以View的事件分发调用super.dispatchTouchEvent()的时候默认把事件传给自己的onTouchEvent处理(相当于拦截),对比ViewGroup的dispatchTouchEvent事件分发,View的事件分发没有上面提到的4个目标的第3点。
ViewGroup和View的onTouchEvent方法是做事件处理的,那么这个事件只能有两个处理方式:
1、自己消费掉,事件终结,不再传给谁—–>
returntrue;
2、继续从下往上传,不消费事件,让父View也能收到到这个事件—–>
View的默认实现是不消费的。
所以super==false。
ViewGroup的onInterceptTouchEvent方法对于事件有两种情况:
1、拦截下来,给自己的onTouchEvent处理—>
2、不拦截,把事件往下传给子View—->
returnfalse,ViewGroup默认是不拦截的,所以super==false;
关于ACTION_MOVE和ACTION_UP
上面讲解的都是针对ACTION_DOWN的事件传递,ACTION_MOVE和ACTION_UP在传递的过程中并不是和ACTION_DOWN一样,你在执行ACTION_DOWN的时候返回了false,后面一系列其它的action就不会再得到执行了。
简单的说,就是当dispatchTouchEvent在进行事件分发的时候,只有前一个事件(如ACTION_DOWN)返回true,才会收到ACTION_MOVE和ACTION_UP的事件。
具体这句话很多博客都说了,但是具体含义是什么呢?
我们来看一下下面的具体分析。
上面提到过了,事件如果不被打断的话是会不断往下传到叶子层(View),然后又不断回传到Activity,dispatchTouchEvent和onTouchEvent可以通过returntrue消费事件,终结事件传递,而onInterceptTouchEvent并不能消费事件,它相当于是一个分叉口起到分流导流的作用,ACTION_MOVE和ACTION_UP会在哪些函数被调用,之前说了并不是哪个函数收到了ACTION_DOWN,就会收到ACTION_MOVE等后续的事件的。
下面通过几张图看看不同场景下,ACTION_MOVE事件和ACTION_UP事件的具体走向并总结一下规律。
1、我们在ViewGroup1的dispatchTouchEvent方法返回true消费这次事件
ACTION_DOWN事件从(Activity的dispatchTouchEvent)——–>
(ViewGroup1的dispatchTouchEvent)后结束传递,事件被消费(如下图红色的箭头代码ACTION_DOWN事件的流向)。
1.//打印日志
2.Activity
|
dispatchTouchEvent
-->
ACTION_DOWN
3.ViewGroup1
4.---->
消费
在这种场景下ACTION_MOVE和ACTION_UP将如何呢,看下面的打出来的日志
1.Activity
ACTION_MOVE
2.ViewGroup1
3.----
4.TouchEventActivity
ACTION_UP
5.ViewGroup1
6.----
下图中
红色的箭头代表ACTION_DOWN事件的流向
蓝色的箭头代表ACTION_MOVE和ACTION_UP事件的流向
2、我们在ViewGroup2的dispatchTouchEvent返回true消费这次事件
onInterceptTouchEvent
4.ViewGroup2
5.---->
6.Activity
7.ViewGroup1
8.ViewGroup1
9.ViewGroup2
10.----
11.TouchEventActivity
12.ViewGroup1
13.ViewGroup1
14.ViewGroup2
15.----
3、我们在View的dispatchTouchEvent返回true消费这次事件
这个我不就画图了,效果和在ViewGroup2的dispatchTouchEventreturntrue的差不多,同样的收到ACTION_DOWN的dispatchTouchEvent函数都能收到ACTION_MOVE和ACTION_UP。
所以我们就基本可以得出结论如果在某个控件的dispatchTouchEvent放回true消费终结事件,那么收到ACTION_DOWN的函数也能收到ACTION_MOVE和ACTION_UP。
4、我们在View的onTouchEvent返回true消费这次事件
5、我们在ViewGroup2的onTouchEvent返回true消费这次事件
6、我们在ViewGroup1的onTouchEvent返回true消费这次事件
7、我们在Activity的onTouchEvent返回true消费这次事件
8、我们在View的dispatchTouchEvent返回false并且Activity的onTouchEvent
返回true消费这次事件
9、我们在View的dispatchTouchEvent返回false并且ViewGroup1的onTouchEvent返回true消费这次事件
10、我们在View的dispatchTouchEvent返回false并且在ViewGroup2的onTouchEvent返回true消费这次事件
11、我们在ViewGroup2的dispatchTouchEvent返回false并且在ViewGroup1的onTouchEvent返回true消费这次事件
12、我们在ViewGroup2的onInterceptTouchEvent返回true拦截此次事件并且在ViewGroup1的onTouchEvent返回true消费这次事件。
一下子画了好多图,还有好几种情况就不再画了,相信你也看出规律了,对于在onTouchEvent消费事件的情况:
在哪个View的onTouchEvent返回true,那么ACTION_MOVE和ACTION_UP的事件从上往下传到这个View后就不再往下传递了,而直接传给自己的onTouchEvent并结束本次事件传递过程。
对于ACTION_MOVE、ACTION_UP总结:
ACTION_DOWN事件在哪个控件消费了(returntrue),那么ACTION_MOVE和ACTION_UP就会从上往下(通过dispatchTouchEvent)做事件分发往下传,就只会传到这个控件,不会继续往下传,如果ACTION_DOWN事件是在dispatchTouchEvent消费,那么事件到此为止停止传递,如果ACTION_DOWN事件是在onTouchEvent消费的,那么会把ACTION_MOVE或ACTION_UP事件传给该控件的onTouchEvent处理并结束传递。
【编辑推荐】
1.Android应用内存泄漏的定位、分析与解决策略
2.基于JavaSocket的自定义协议,实现Android与服务器的长连接
(一)
3.基于JavaSocket的自定义协议,实现Android与服务器的长连接
(二)
4.34个Android常用adbshell命令汇总
5.Android开发中的MVP架构
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 图解 Android 事件 分发 机制