Android 事件分发机制 图解
在Android 开发中事件分发是比较重要的,也是比较难理解的,之前看过这方面的东西,以为自己弄懂了,也就没太注意,最近面试呢,想着肯定要问到这一块的东西,回顾的时候发现又忘了,真是好记性不如烂笔头啊,长期没有用到这一块的东西,也就抛之脑后了,今天用了半天时间,看资料有了解了一下,把这块内容整理一下,省的以后在以后学习过程中,要不断温故一下,看的时候就不用那么麻烦了。
文章参考于:http://www.jianshu.com/p/e99b5e8bd67b
下面就是事件分发的流程图:
- 仔细看的话,图分为3层,从上往下依次是Activity、ViewGroup、View
- 事件从左上角那个白色箭头开始,由Activity的dispatchTouchEvent做分发
- 箭头的上面字代表方法返回值,(return true、return false、return super.xxxxx(),super 的意思是调用父类实现。
- dispatchTouchEvent和 onTouchEvent的框里有个【true---->消费】的字,表示的意思是如果方法返回true,那么代表事件就此消费,不会继续往别的地方传了,事件终止。
- 目前所有的图的事件是针对ACTION_DOWN的,对于ACTION_MOVE和ACTION_UP我们最后做分析。
- 之前图中的Activity 的dispatchTouchEvent 有误(图已修复),只有return super.dispatchTouchEvent(ev) 才是往下走,返回true 或者 false 事件就被消费了(终止传递)。
仔细看整个图,我们得出事件流 走向的几个结论(希望读者专心的看下图 1,多看几遍,脑子有比较清晰的概念。)
1、如果事件不被中断,整个事件流向是一个类U型图,我们来看下这张图,可能更能理解U型图的意思。
看上图深蓝色的线,对于返回false的情况,事件都是传给父控件onTouchEvent处理。
- 对于dispatchTouchEvent 返回 false 的含义应该是:事件停止往子View传递和分发同时开始往父控件回溯(父控件的onTouchEvent开始从下往上回传直到某个onTouchEvent return true),事件分发机制就像递归,return false 的意义就是递归停止然后开始回溯。
- 对于onTouchEvent return false 就比较简单了,它就是不消费事件,并让事件继续往父控件的方向从下往上流动。
4、dispatchTouchEvent、onTouchEvent、onInterceptTouchEvent
ViewGroup 和View的这些方法的默认实现就是会让整个事件安装U型完整走完,所以 return super.xxxxxx() 就会让事件依照U型的方向的完整走完整个事件流动路径),中间不做任何改动,不回溯、不终止,每个环节都走到。
所以如果看到方法return super.xxxxx() 那么事件的下一个流向就是走U型下一个目标,稍微记住上面这张图,你就能很快判断出下一个走向是哪个控件的哪个函数。
5、onInterceptTouchEvent 的作用
Intercept 的意思就拦截,每个ViewGroup每次在做分发的时候,问一问拦截器要不要拦截(也就是问问自己这个事件要不要自己来处理)如果要自己处理那就在onInterceptTouchEvent方法中 return true就会交给自己的onTouchEvent的处理,如果不拦截就是继续往子控件往下传。默认是不会去拦截的,因为子View也需要这个事件,所以onInterceptTouchEvent拦截器return super.onInterceptTouchEvent()和return false是一样的,是不会拦截的,事件会继续往子View的dispatchTouchEvent传递。
6、ViewGroup 和View 的dispatchTouchEvent方法返回super.dispatchTouchEvent()的时候事件流走向。
那么对于View的dispatchTouchEvent return super.dispatchTouchEvent()的时候呢事件会传到哪里呢,很遗憾View没有拦截器。但是同样的道理return true是终结。return false 是回溯会父类的onTouchEvent,怎样把事件分发给自己的onTouchEvent 处理呢,那只能return super.dispatchTouchEvent,View类的dispatchTouchEvent()方法默认实现就是能帮你调用View自己的onTouchEvent方法的。
说了这么多,不知道有说清楚没有,我这边最后总结一下:
- 对于 dispatchTouchEvent,onTouchEvent,return true是终结事件传递。return false 是回溯到父View的onTouchEvent方法。
- ViewGroup 想把自己分发给自己的onTouchEvent,需要拦截器onInterceptTouchEvent方法return true 把事件拦截下来。
- ViewGroup 的拦截器onInterceptTouchEvent 默认是不拦截的,所以return super.onInterceptTouchEvent()=return false;
- View 没有拦截器,为了让View可以把事件分发给自己的onTouchEvent,View的dispatchTouchEvent默认实现(super)就是把事件分发给自己的onTouchEvent。
ViewGroup和View 的dispatchTouchEvent 是做事件分发,那么这个事件可能分发出去的四个目标
注:------> 后面代表事件目标需要怎么做。
1、 自己消费,终结传递。------->return true ;
2、 给自己的onTouchEvent处理-------> 调用super.dispatchTouchEvent()系统默认会去调用 onInterceptTouchEvent,在onInterceptTouchEvent return true就会去把事件分给自己的onTouchEvent处理。
3、 传给子View------>调用super.dispatchTouchEvent()默认实现会去调用 onInterceptTouchEvent 在onInterceptTouchEvent return false,就会把事件传给子类。
4、 不传给子View,事件终止往下传递,事件开始回溯,从父View的onTouchEvent开始事件从下到上回归执行每个控件的onTouchEvent------->return false;
注: 由于View没有子View所以不需要onInterceptTouchEvent 来控件是否把事件传递给子View还是拦截,所以View的事件分发调用super.dispatchTouchEvent()的时候默认把事件传给自己的onTouchEvent处理(相当于拦截),对比ViewGroup的dispatchTouchEvent 事件分发,View的事件分发没有上面提到的4个目标的第3点。
ViewGroup和View的onTouchEvent方法是做事件处理的,那么这个事件只能有两个处理方式:
1、自己消费掉,事件终结,不再传给谁----->return true;
2、继续从下往上传,不消费事件,让父View也能收到到这个事件----->return false;View的默认实现是不消费的。所以super==false。
ViewGroup的onInterceptTouchEvent方法对于事件有两种情况:
1、拦截下来,给自己的onTouchEvent处理--->return true;
2、不拦截,把事件往下传给子View---->return false,ViewGroup默认是不拦截的,所以super==false;
Android 事件分发机制 图解的更多相关文章
- Android事件分发机制(下)
这篇文章继续讨论Android事件分发机制,首先我们来探讨一下,什么是ViewGroup?它和普通的View有什么区别? 顾名思义,ViewGroup就是一组View的集合,它包含很多的子View和子 ...
- Android事件分发机制(上)
Android事件分发机制这个问题不止一个人问过我,每次我的回答都显得模拟两可,是因为自己一直对这个没有很好的理解,趁现在比较闲对这个做一点总结 举个例子: 你当前有一个非常简单的项目,只有一个Act ...
- android事件分发机制
android事件分发机制,给控件设置ontouch监听事件,当ontouch返回true时,他就不会走onTouchEvent方法,要想走onTouchEvent方法只需要返回ontouch返回fa ...
- [转]Android事件分发机制完全解析,带你从源码的角度彻底理解(上)
Android事件分发机制 该篇文章出处:http://blog.csdn.net/guolin_blog/article/details/9097463 其实我一直准备写一篇关于Android事件分 ...
- Android事件分发机制源码分析
Android事件分发机制源码分析 Android事件分发机制源码分析 Part1事件来源以及传递顺序 Activity分发事件源码 PhoneWindow分发事件源码 小结 Part2ViewGro ...
- 【转】Android事件分发机制完全解析,带你从源码的角度彻底理解(下)
转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/9153761 记得在前面的文章中,我带大家一起从源码的角度分析了Android中Vi ...
- 【自己定义控件】android事件分发机制
自己定义Viewgrou中我们或许会常常碰到这种情况,2个子控件的事件冲突导致滑动没实用了.滑动反应非常慢,点击没用了,要划非常多次才移动一点点等等.或许我们第一反应就是百度,google去搜索下答案 ...
- Android 事件分发机制具体解释
很多其它内容请參照我的个人网站: http://stackvoid.com/ 网上非常多关于Android事件分发机制的解释,大多数描写叙述的都不够清晰,没有吧来龙去脉搞清晰,本文将带你从Touch事 ...
- 【朝花夕拾】Android自定义View篇之(六)Android事件分发机制(中)从源码分析事件分发逻辑及经常遇到的一些“诡异”现象
前言 转载请注明,转自[https://www.cnblogs.com/andy-songwei/p/11039252.html]谢谢! 在上一篇文章[[朝花夕拾]Android自定义View篇之(五 ...
随机推荐
- uva 177:Paper Folding(模拟 Grade D)
题目链接 题意:一张纸,每次从右往左对折.折好以后打开,让每个折痕都自然的呈90度.输出形状. 思路:模拟折……每次折想象成把一张纸分成了正面在下的一张和反面在上的一张.维护左边和方向,然后输出.细节 ...
- CSU 1785: 又一道简单题
1785: 又一道简单题 Submit Page Summary Time Limit: 5 Sec Memory Limit: 128 Mb Submitted: 602 ...
- [Machine Learning with Python] My First Data Preprocessing Pipeline with Titanic Dataset
The Dataset was acquired from https://www.kaggle.com/c/titanic For data preprocessing, I firstly def ...
- codevs——1169 传纸条(棋盘DP)
2008年NOIP全国联赛提高组 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题解 查看运行结果 题目描述 Description 小渊和小 ...
- NULL和唯一约束UNIQUE的对应关系
NULL和唯一约束UNIQUE的对应关系 在数据库中,NULL表示列值为空.唯一约束UNIQUE规定指定列的值必须是唯一的,值和值之间都不能相同.这个时候,就出现一个问题,NULL和NULL算是相 ...
- golang实现dns域名解析(二)
上一节已经讲了如何构造dns请求包的情况,这一节接着上一节的情况,谈谈dns查询报文中的问题部分.问题部分中每个问题的格式如下: 查询名是要查找的名字,它是一个或者多个标识符的序列.每个标识符以首字母 ...
- [资料分享]GIS+=地理信息+云计算+大数据+容器+物联网+...论文、会议、讲座资料分享
分享地址 http://pan.baidu.com/s/1gesDSB5 部分内容截图 watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5 ...
- HDU2550 百步穿杨
百步穿杨 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submi ...
- TRIZ系列-创新原理-20-有效作用的连续性原理
有效作用的连续性原理表述例如以下:1)连续实施动作不要中断,物体的全部部分应该一直处于满负荷工作状态.2)去除全部空暇的,中间的动作:3)用循环的动作取代"来来回回"的动作: 这个 ...
- 转: https 加密通信流程
https 加密通信流程当用户在浏览器中输入一个以https开头的网址时,便开启了浏览器与被访问站点之间的加密通信.下面我们以一个用户访问https://qbox.me为例,给读者展现一下SSL/TL ...