事件分发机制详解

一、基础知识介绍

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方法。

  1. 所处的view拦截了事件
  2. 没有子View
  3. 子View都不消费事件

2、onTouchListener中的onTouch回调与dispatchTouchEvent的优先级一样,都是优先于onTouchEvent的

Android事件分发机制详解的更多相关文章

  1. Android事件分发机制详解(2)----分析ViewGruop的事件分发

    首先,我们需要 知道什么是ViewGroup,它和普通的View有什么区别? ViewGroup就是一组View的集合,它包含很多子View和ViewGroup,是Android 所有布局的父类或间接 ...

  2. android 事件分发机制详解(OnTouchListener,OnClick)

    昨天做东西做到触摸事件冲突,以前也经常碰到事件冲突,想到要研究一下Android的事件冲突机制,于是从昨天开始到今天整整一天时间都要了解这方面的知识,这才懂了安卓的触摸和点击事件的机制.探究如下: 首 ...

  3. Android事件分发机制详解(1)----探究View的事件分发

    探究View的事件分发 在Activity中,只有一个按钮,注册一个点击事件 [java] view plaincopy button.setOnClickListener(new OnClickLi ...

  4. Android事件传递机制详解及最新源码分析——ViewGroup篇

    版权声明:本文出自汪磊的博客,转载请务必注明出处. 在上一篇<Android事件传递机制详解及最新源码分析--View篇>中,详细讲解了View事件的传递机制,没掌握或者掌握不扎实的小伙伴 ...

  5. Android开发——事件分发机制详解

    0. 前言   转载请注明出处:http://blog.csdn.net/seu_calvin/article/details/52566965 深入学习事件分发机制,是为了解决在Android开发中 ...

  6. Android View 事件分发机制详解

    想必很多android开发者都遇到过手势冲突的情况,我们一般都是通过内部拦截和外部拦截法解决此类问题.要想搞明白原理就必须了解View的分发机制.在此之前我们先来了解一下以下三个非常重要的方法: di ...

  7. IOS 触摸事件分发机制详解

    欢迎大家前往云+社区,获取更多腾讯海量技术实践干货哦~ 作者:MelonTeam 前言 很多时候大家都不关心IOS触摸事件的分发机制的实现原理,当遇到以下几种情形的时候你很可能抓破头皮都找不到解决方案 ...

  8. Android事件传递机制详解及最新源码分析——View篇

    摘要: 版权声明:本文出自汪磊的博客,转载请务必注明出处. 对于安卓事件传递机制相信绝大部分开发者都听说过或者了解过,也是面试中最常问的问题之一.但是真正能从源码角度理解具体事件传递流程的相信并不多, ...

  9. 【Android面试查漏补缺】之事件分发机制详解

    前言 查漏补缺,查漏补缺,你不知道哪里漏了,怎么补缺呢?本文属于[Android面试查漏补缺]系列文章第一篇,持续更新中,感兴趣的朋友可以[关注+收藏]哦~ 本系列文章是对自己的前段时间面试经历的总结 ...

随机推荐

  1. 学习H5一周随笔

    H5学习也已经进行了一个周了,除了学习过程中的乱哄哄的脑子,对H5初学者(我)常见的问题有了如下见解. 1.初学者在建立新的Html文件之后,有时候会把 <meta charset=" ...

  2. (10)集合之双列集合Map,HashMap,TreeMap

    Map中的元素是两个对象,一个对象作为键,一个对象作为值.键不可以重复,但是值可以重复. 看顶层共性方法找子类特有对象. Map与Collection在集合框架中属并列存在 Map存储的是键值对 Ma ...

  3. java中有符号和无符号数据类型发生转换

    package com.itheima.test01;/* * byte short int long float double 是有符号位的数 * char boolean 是无符号位的数 * 补码 ...

  4. 解读web服务器与php的工作原理

    最近决定重读php手册(好吧,其实之前也没怎么读,尴尬脸),既然是重读,那就从php的安装开始咯,然后被手册中出现的各种新词搞懵逼了,什么cgi.fastcgi.sapi.fpm,苍天啊,这些都是什么 ...

  5. supervisor的集中化管理搭建

    1.supervisor很不错,可惜是单机版,所以上github上找了个管理工具supervisord-monitor. github地址: https://github.com/mlazarov/s ...

  6. JavaScript复习之--javascript数据类型隐式转换

    JavaScript数据类型隐式转换.一,函数类    isNaN()    该函数会对参数进行隐式的Number()转换,如果转换不成功则返回true.    alert()    输出的内容隐式的 ...

  7. flex盒子里面元素linehight对高度的影响

    那天,高高兴兴的测试flex属性.大家都知道,当父盒子display:flex的时候,子盒子即使宽高和大于父盒子,也会由于flex的特性进行收缩:然而,在给父盒子加了flex-direction:co ...

  8. centos 6.5 搭建JSP运行环境

    一.安装nginx yum install nginx #安装nginx,根据提示,输入Y安装即可成功安装 service nginx start #启动 chkconfig nginx on #设为 ...

  9. P2物理引擎中文文档

    P2物理引擎中文文档地址:https://github.com/schteppe/p2.js/wiki/Chinese-wiki-%E4%B8%AD%E6%96%87%E7%BB%B4%E5%9F%B ...

  10. CDIF:基于JSON的SOA软件框架

    通用设备互联框架(CDIF)是一个具备中美知识产权保护的,基于web的连接框架,目前有部分开源实现存放在: GitHub - out4b/cdif: Common device interconnec ...