图解Android事件分发机制文档格式.docx

上传人:b****5 文档编号:17418779 上传时间:2022-12-01 格式:DOCX 页数:16 大小:1.50MB
下载 相关 举报
图解Android事件分发机制文档格式.docx_第1页
第1页 / 共16页
图解Android事件分发机制文档格式.docx_第2页
第2页 / 共16页
图解Android事件分发机制文档格式.docx_第3页
第3页 / 共16页
图解Android事件分发机制文档格式.docx_第4页
第4页 / 共16页
图解Android事件分发机制文档格式.docx_第5页
第5页 / 共16页
点击查看更多>>
下载资源
资源描述

图解Android事件分发机制文档格式.docx

《图解Android事件分发机制文档格式.docx》由会员分享,可在线阅读,更多相关《图解Android事件分发机制文档格式.docx(16页珍藏版)》请在冰豆网上搜索。

图解Android事件分发机制文档格式.docx

注:

∙仔细看的话,图分为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架构

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 总结汇报 > 学习总结

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1