Android事件分发机制详解
事件分发机制详解
一、基础知识介绍
1、经常用的事件有:MotionEvent.ACTION_DOWN,MotionEvent.ACTION_MOVE,MotionEvent.ACTION_UP等
2、常用的方法有:disPatchTouchEvent(),onTouchEvent(),onInterceptTouchEvent()(只有ViewGroup才有这个方法,View没有这个方法,且ViewGroup是View的子类);
二、方法功能介绍
1、dispatchTouchEvent事件分发的调度者与指挥者,触发的第一个方法
2、onInterceptTouchEvent,决定是否拦截事件:
3、如果拦截事件,调用当前控件的onTouchEvent方法,
4、如果不拦截,判断是否有子控件,
5、onTouchEvent,决定是否消费事件,消费返回True,不消费返回False。如果返回的为false,之后的事件都不会再传递到当前的控件了(会不再访问当前控件),如果返回true,之后的事件依然还是会传递过来的。
三、各个方法和控件之间事件传递关系
事件传递流程:事件—>Activity—>Window—>DecorView—>ViewTree(嵌套在一起的各种控件)
一个事件,首先会由Activity的dispatchTouchEvent方法接受,然后分发到附着在Activity上的Window,Window不进行处理直接分发到ViewTree;最外层的ViewTop(默认为是ViewGroup类型的)会先调用自己的dispatchTouchEvent方法,然后由dispatchTouchEvent调用onInterceptTouchEvent方法,如果返回true,调用自己的onTouchEvent方法;如果返回false,继续向下一个控件进行事件分发。
如果ViewTree中的所有控件都不消费,那就返回到Activity中,由Activity调用onTouchEvent方法。
下面给大家一个具体的例子,大家可以有一个形象的感受。
四、示例Demo(示例中的代码是不考虑下面说的特殊情况的)
布局文件
<VP1>
<VP2>
<CustomView/>
</VP2>
</VP1>
1、控件都不消费
down事件
Log:-Activity:dispatchTouchEvent:调用
Log:-VP1:dispatchTouchEvent:调用
Log:-VP1:onInterceptTouchEvent:调用
Log:-VP1:onInterceptTouchEvent:返回:false
Log:-VP2:dispatchTouchEvent:调用
Log:-VP2:onInterceptTouchEvent:调用
Log:-VP2:onInterceptTouchEvent:返回:false
Log:-CustomView:dispatchTouchEvent:调用
Log:-CustomView:touchEvent:调用
Log:-CustomView:touchEvent:返回:false
Log:-CustomView:dispatchTouchEvent:返回:false
Log:-VP2:touchEvent:调用
Log:-VP2:touchEvent:返回:false
Log:-VP2:dispatchTouchEvent:返回:false
Log:-VP1:touchEvent:调用
Log:-VP1:touchEvent:返回:false
Log:-VP1:dispatchTouchEvent:返回:false
Log:-Activity:touchEvent:调用
Log:-Activity:touchEvent:返回:false
Log:-Activity:dispatchTouchEvent:返回:false
up事件
Log:-Activity:dispatchTouchEvent:调用
Log:-Activity:touchEvent:调用
Log:-Activity:touchEvent:返回:false
Log:-Activity:dispatchTouchEvent:返回:false
2、CustomView消费
down事件
Log:-Activity:dispatchTouchEvent:调用
Log:-VP1:dispatchTouchEvent:调用
Log:-VP1:onInterceptTouchEvent:调用
Log:-VP1:onInterceptTouchEvent:返回:false
Log:-VP2:dispatchTouchEvent:调用
Log:-VP2:onInterceptTouchEvent:调用
Log:-VP2:onInterceptTouchEvent:返回:false
Log:-CustomView:dispatchTouchEvent:调用
Log:-CustomView:touchEvent:调用
Log:-CustomView:touchEvent:返回:true
Log:-CustomView:dispatchTouchEvent:返回:true
Log:-VP2:dispatchTouchEvent:返回:true
Log:-VP1:dispatchTouchEvent:返回:true
Log:-Activity:dispatchTouchEvent:返回:true
Up事件
Log:-Activity:dispatchTouchEvent:调用
Log:-VP1:dispatchTouchEvent:调用
Log:-VP1:onInterceptTouchEvent:调用
Log:-VP1:onInterceptTouchEvent:返回:false
Log:-VP2:dispatchTouchEvent:调用
Log:-VP2:onInterceptTouchEvent:调用
Log:-VP2:onInterceptTouchEvent:返回:false
Log:-CustomView:dispatchTouchEvent:调用
Log:-CustomView:touchEvent:调用
Log:-CustomView:touchEvent:返回:true
Log:-CustomView:dispatchTouchEvent:返回:true
Log:-VP2:dispatchTouchEvent:返回:true
Log:-VP1:dispatchTouchEvent:返回:true
Log:-Activity:dispatchTouchEvent:返回:true
3、VP2拦截不消费
Down事件
Log:-Activity:dispatchTouchEvent:调用
Log:-VP1:dispatchTouchEvent:调用
Log:-VP1:onInterceptTouchEvent:调用
Log:-VP1:onInterceptTouchEvent:返回:false
Log:-VP2:dispatchTouchEvent:调用
Log:-VP2:onInterceptTouchEvent:调用
Log:-VP2:onInterceptTouchEvent:返回:true
Log:-VP2:touchEvent:调用
Log:-VP2:touchEvent:返回:false
Log:-VP2:dispatchTouchEvent:返回:false
Log:-VP1:touchEvent:调用
Log:-VP1:touchEvent:返回:false
Log:-VP1:dispatchTouchEvent:返回:false
Log:-Activity:touchEvent:调用
Log:-Activity:touchEvent:返回:false
Log:-Activity:dispatchTouchEvent:返回:false
UP事件
Log:-Activity:dispatchTouchEvent:调用
Log:-Activity:touchEvent:调用
Log:-Activity:touchEvent:返回:false
Log:-Activity:dispatchTouchEvent:返回:false
4、VP2拦截消费
Down事件
Log:-Activity:dispatchTouchEvent:调用
Log:-VP1:dispatchTouchEvent:调用
Log:-VP1:onInterceptTouchEvent:调用
Log:-VP1:onInterceptTouchEvent:返回:false
Log:-VP2:dispatchTouchEvent:调用
Log:-VP2:onInterceptTouchEvent:调用
Log:-VP2:onInterceptTouchEvent:返回:true
Log:-VP2:touchEvent:调用
Log:-VP2:touchEvent:返回:true
Log:-VP2:dispatchTouchEvent:返回:true
Log:-VP1:dispatchTouchEvent:返回:true
Log:-Activity:dispatchTouchEvent:返回:true
UP事件
Log:-Activity:dispatchTouchEvent:调用
Log:-VP1:dispatchTouchEvent:调用
Log:-VP1:onInterceptTouchEvent:调用
Log:-VP1:onInterceptTouchEvent:返回:false
Log:-VP2:dispatchTouchEvent:调用
Log:-VP2:touchEvent:调用
Log:-VP2:touchEvent:返回:true
Log:-VP2:dispatchTouchEvent:返回:true
Log:-VP1:dispatchTouchEvent:返回:true
Log:-Activity:dispatchTouchEvent:返回:true
五、特殊情况
1、如果disallowIntercept=true,那么不会再走控件中的onInterceptTouchEvent方法,直接标记为不拦截事件。
2、如果有requestDisallowInterceptTouchEvent(true)方法,父类控件不走onInterceptTouchEvent方法,不用通过回调来判断是否需要拦截事件,而是直接进行传送。
3、这两方面,主要是用来解决手势冲突的。
六、小提示
1、如果满足下列条件之一,就会调用onTouchEvent方法。
- 所处的view拦截了事件
- 没有子View
- 子View都不消费事件
2、onTouchListener中的onTouch回调与dispatchTouchEvent的优先级一样,都是优先于onTouchEvent的
Android事件分发机制详解的更多相关文章
- Android事件分发机制详解(2)----分析ViewGruop的事件分发
首先,我们需要 知道什么是ViewGroup,它和普通的View有什么区别? ViewGroup就是一组View的集合,它包含很多子View和ViewGroup,是Android 所有布局的父类或间接 ...
- android 事件分发机制详解(OnTouchListener,OnClick)
昨天做东西做到触摸事件冲突,以前也经常碰到事件冲突,想到要研究一下Android的事件冲突机制,于是从昨天开始到今天整整一天时间都要了解这方面的知识,这才懂了安卓的触摸和点击事件的机制.探究如下: 首 ...
- Android事件分发机制详解(1)----探究View的事件分发
探究View的事件分发 在Activity中,只有一个按钮,注册一个点击事件 [java] view plaincopy button.setOnClickListener(new OnClickLi ...
- Android事件传递机制详解及最新源码分析——ViewGroup篇
版权声明:本文出自汪磊的博客,转载请务必注明出处. 在上一篇<Android事件传递机制详解及最新源码分析--View篇>中,详细讲解了View事件的传递机制,没掌握或者掌握不扎实的小伙伴 ...
- Android开发——事件分发机制详解
0. 前言 转载请注明出处:http://blog.csdn.net/seu_calvin/article/details/52566965 深入学习事件分发机制,是为了解决在Android开发中 ...
- Android View 事件分发机制详解
想必很多android开发者都遇到过手势冲突的情况,我们一般都是通过内部拦截和外部拦截法解决此类问题.要想搞明白原理就必须了解View的分发机制.在此之前我们先来了解一下以下三个非常重要的方法: di ...
- IOS 触摸事件分发机制详解
欢迎大家前往云+社区,获取更多腾讯海量技术实践干货哦~ 作者:MelonTeam 前言 很多时候大家都不关心IOS触摸事件的分发机制的实现原理,当遇到以下几种情形的时候你很可能抓破头皮都找不到解决方案 ...
- Android事件传递机制详解及最新源码分析——View篇
摘要: 版权声明:本文出自汪磊的博客,转载请务必注明出处. 对于安卓事件传递机制相信绝大部分开发者都听说过或者了解过,也是面试中最常问的问题之一.但是真正能从源码角度理解具体事件传递流程的相信并不多, ...
- 【Android面试查漏补缺】之事件分发机制详解
前言 查漏补缺,查漏补缺,你不知道哪里漏了,怎么补缺呢?本文属于[Android面试查漏补缺]系列文章第一篇,持续更新中,感兴趣的朋友可以[关注+收藏]哦~ 本系列文章是对自己的前段时间面试经历的总结 ...
随机推荐
- 用Use Case获取需求的方法是否有什么缺陷,还有什么地方需要改进?
一.用例解释 用例是一种在开发新系统或者软件改造时捕获潜在需求的技术.每个用例提供了一个或多个场景,该场景揭示了系统是如何同最终用户或其它系统交互的,从而获得一个明确的业务目标.用例要避免技术术语,取 ...
- Hibernate打印SQL及附加参数
今天在项目运行过程中,一直报一个org.hibernate.exception.GenericJDBCException: could not insert 异常,Root Cause是IBM DB ...
- 3.java的hello word.继承.泛型.反射.配置项.数据库操作.lombok
迷迷茫茫的开始了第一步.弄个hello word.结果这第一小步也不是那么的顺利. 明明照着图敲的.可就是没有运行选项. 为此还百度了一下.也没有什么答案.最后只能老老实实的看了.结果还是粗心的问题. ...
- 使用slice和concat对数组的深拷贝和浅拷贝
一.数组浅拷贝 在使用JavaScript对数组进行操作的时候,我们经常需要将数组进行备份. 如下代码,如果只是简单才用赋值的方法,那么我们只要更改其中的任何一个,然后其他的也会跟着改变,这就导致了问 ...
- javascript继承--原型链的 继承
作者的话:原型链是JavaScript中相当重要的一个知识点,这里我使用了函数结构图,来帮助我更好的理解 /* 原型链继承方式: 通过改变一个对象的原型对象的指向来继承另一个对象 原理: 我们知道,一 ...
- IOS推送--之开发模式测试
参考文章:http://blog.csdn.net/showhilllee/article/details/8631734#comments 第一步.下载你工程的开发证书 第二步.从钥匙串访问中导出秘 ...
- 开源一个vue2的tree组件
一直打算偷懒使用个现成的树组件,但是在github上找了一大圈没有找到真正满足应用开发的树组件,所以没办法只能自己写了一个,开源出来希望可以帮助到需要的人,同时如果大家觉得好用,我可以顺带骗骗★(希望 ...
- 微信web开发者工具使用
1.首先启动微信web开发者工具, 2.启动之后,点击移动端调试, 3.选择普通调试,然后,将手机和电脑置于同一个网段之中,可以通过电脑发出一个wifi,让手机连入就行 4.如果,电脑室台式机的话,没 ...
- Oracle SQL 语言分类
Oracle SQL语句分类 2008-06-17 11:15:25 分类: Linux * 2008/06/17 星期二*蒙昭良*环境:WindowsXP + Oracle10gR2*Oracl ...
- linux系统使用python监测网络接口获取网络的输入输出
#!/usr/bin/env Pythonimport timeimport sys if len(sys.argv) > 1: INTERFACE = sys.argv[1]else: INT ...