Android事件分发(刷新认知,带你远离网络上的错误知识)

最近想复习一下View事件传递的知识,之前写过好多自定义控件,可最近没咋接触这块知识,又快忘了,所以上网搜一下资料,发现大部分的资料都不全,很多都存有漏洞,甚至是错误的,包括在最近看的一本书 《Android 框架体系架构》上面的介绍,图片,也存在一些错误 ,所以自己通过看源码以及观察代码执行结果来分析事件传递的真理.

目录

1、基本流程与注意点

1、总结:

一、分发器(dispatchTouchEvent()) :

二、拦截器(interceptTouchEvent())

三、消费器(onTouchEvent())

2、完整流程图


本文从事件类型、事件处理方法两个层面结合来分析.

1、基本流程与注意点

先看一张图,图中所画的流程,是一个简单的,完整的事件流程图,图层嵌套 由外到内 为Activity -->Viewgroup1-->Viewgroup2-->View .绘图功底不太好,敬请谅解:

点击事件分发流程图

注意点:图中所画的是一个点击事件的流程图,为什么说是点击事件呢,因为移动、抬起、取消事件的流程跟他不一样,他们都会收到点击事件流程的限制,总结一句话就是,点击事件被处理的那一层View(Activity、Viewgroup),将会是后续的移动、抬起、取消事件所能到达的最内层(或最底层),举个例子:

在一套完整的手势当中(点击>滑动>抬起),点击事件被上图中的Viewgroup2# onTouchEvent所消费(返回true),点击事件到此终止,接下来的移动事件,抬起事件,到达Viewgroup2#dispatchTouchEvent()之后,如果返回false(因为返回true,事件结束不再处理),则事件直接由Viewgroup2#onTouchEvent()处理,不再经过interceptTouchEvent(),也就是说,系统会认为Viewgroup2是一个View, 忽略内部所有子控件,不再向内传递事件,且不调用interceptTouchEvent 方法(可以把他理解为一个View 而不是viewgroup 了).

 

1、总结:

注:“任何事件”表示 包括点击、滑动、抬起、取消手势.

一、分发器(dispatchTouchEvent()) :

1、处理任何事件——返回true,则事件结束,不再传递.

2、但是,处理任何事件——返回False,事件都会走到本层的拦截器(interceptTouchEvent())处理吗? 第一张图片下面的说明已经告诉我们结果,答案是否定的!

(1)如果处理点击事件的时候,事件被本层onTouchEvent()所消费(返回true),那么本层View 的拦截器会被忽略掉,本层无论是View还是Viewgroup,都会被当成一个View处理.

(2)若所有层级都没有处理点击事件,那么后续的所有事件将会直接在activity中处理,不再下发给内层的View(以及GroupView),也就是说如果activity #dispatchTouchEvent()返回false,直接调用activity#onTouchEvent,无论onTouchEvent 是否会处理消费.

二、拦截器(interceptTouchEvent())

1、Activity与非容器View没有拦截器.

2、处理任何事件返回true,则事件传递本层View的消费器(onTouchEvent()).

3、如果返回false,则向下传播,到内层View的dispatchTouchEvent(如果没有子View,与返回true同样效果,将事件传递本层View的消费器(onTouchEvent()).

三、消费器(onTouchEvent())

1、在处理点击事件返回true,则事件直接结束,不再传递.

2、那么消费点击事件的那一层View(或viewgroup)在处理后面的其他事件的时候,返回true/false,都有什么区别呢?(不考虑这层View的内层View ,因为内层View未处理点击事件,已被系统忽略)

(1)在处理点击事件的时候,如果返回true,后续事件将会忽略除了Activity以及本层View之外的所有View的onTouchEvent(),也就是说,你不处理点击事件,或者点击事件被其他View所消费,那么与这个点击事件相关的后续滑动、抬起事件将会自动忽略你.只有Activity的onTouchEvent比较特殊一点点.

(2)为什么说Activity的onTouchEvent比较特殊,是因为 ,如果消费了点击事件的那一层View如果不消费后续的滑动、抬起事件,那么事件会直接传递到Activity#onTouchEvent中

那么我们就可以得出第四条

四、消费器(onTouchEvent()) 在处理移动、取消、抬起事件返回true,则事件直接传递到Activity的消费器(onTouchEvent())----(无论是View还是ViewGroup,也无论中间还有多少层级,直接跨过到Activity).(注意不包括点击事件)

可能你也看出来了,消费器(onTouchEvent())在处理点击事件的时候,也扮演着一个拦截器的作用,消费点击事件的那一层View,将会变成后续事件可到达的最底层,这一层 View无论内部还有没有子View,事件都不会再去传递.

上面四点如果你看的有点儿懵懂,混乱,的话,可能你需要多点儿耐心,再看一遍,因为这是整个事件流程的核心部分,当然也可以先看后面的流程图,跟上文进行验证对比来理解,可能更容易一点:

2、完整流程图

点击事件完整流程图

滑动、抬起手势流程图

上面这两个图片是对第一点“总结”当中的思维走向,流程图表达的方式是以满足逻辑走向为主,与上方的文字相结合来理解比较好懂一些.

若有不对的地方欢迎指正!

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值