Android事件分发机制是个难点和重点,结合下各家,写点自己的理解。。

首先抛出一个小问题,写一个button的点击事件

  1. button.setOnClickListener(new OnClickListener() {
  2. @Override
  3. public void onClick(View v) {
  4. Log.d("TAG", "onClick execute");

再写一个button的touch事件

  1. button.setOnTouchListener(new OnTouchListener() {
  2. @Override
  3. public boolean onTouch(View v, MotionEvent event) {
  4. Log.d("TAG", "onTouch execute, action " + event.getAction());
  5. return false;
  6. }
  7. });

结果:

如果把ontouch方法返回值改为true,结果:

这是为什么?你先可以理解为返回true被消费了,不会往下传递了。

你触摸到了任何一个控件,就一定会调用该控件的dispatchTouchEvent方法。那当我们去点击按钮的时候,就会去调用Button类里的dispatchTouchEvent方法,可是你会发现Button类里并没有这个方法,那么就到它的父类TextView里去找一找,你会发现TextView里也没有这个方法,那没办法了,只好继续在TextView的父类View里找一找,这个时候你终于在View里找到了这个方法,示意图如下:

然后我们来看一下View中dispatchTouchEvent方法的源码:

  1. public boolean dispatchTouchEvent(MotionEvent event) {
  2. if (mOnTouchListener != null && (mViewFlags & ENABLED_MASK) == ENABLED &&
  3. mOnTouchListener.onTouch(this, event)) {
  4. return true;
  5. }
  6. return onTouchEvent(event);
  7. }

看这个就明白了:刚才我们修改的outouch()方法return true,那么就走上面的if语句,被消费了没有执行click方法,如果outouch()ruturn false,那么dispatchTouchEvent()就ruturn onTouchEvent(event),说明了click方法一定在outouchEvent方法里面,点进去看下,果然

  1. public boolean performClick() {
  2. sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_CLICKED);
  3. if (mOnClickListener != null) {
  4. playSoundEffect(SoundEffectConstants.CLICK);
  5. mOnClickListener.onClick(this);
  6. return true;
  7. }
  8. return false;
  9. }

****************************************************************************************************************************
接下来我们看一个图

理解自:

注意:

  • 目前所有的图的事件是针对ACTION_DOWN的,对于ACTION_MOVE和ACTION_UP后面再说。

然后总结一下:1.有三层,Activity,ViewGroup,View, 然后呢,分别是dispatchTouchEvent,onInterceptTouchEvent,onTouchEvent,理解为分发,拦截,消费,因为Activity和view在最上和最底层,所以没有onInterceptTouchEvent.

2,接下来认真看下图,有三种返回值,return true,return false, return super,如果只走return super的话那么就是一个U型,整个流程应该是Activity---->ViewGroup--->View 从上往下调用dispatchTouchEvent方法,一直到叶子节点(View)的时候,再由View--->ViewGroup--->Activity从下往上调用onTouchEvent方法。

只要分析dispatchTouchEvent它的四条线路就可以理解这幅图

3.线路1:dispatchTouchEvent和onTouchEvent只要是返回true就是被消费了,没了,不会往下传了

4.线路2:dispatchTouchEvent和onTouchEvent只要是返回false就会回溯给父空间的onTouchEvent处理,类似递归停止开始回溯。

5.dispatchTouchEvent返回super.XXXX()那么就会交给这个ViewGroup的onInterceptTouchEvent 来处理,onInterceptTouchEvent (意思拦截,就是ViewGrouo分发的时候,问一问要不要拦截,如果拦截返回true,如果不拦截返回false,默认return super.onInterceptTouchEvent()就是return false),这里面再分两条路,线路3:到了onInterceptTouchEvent 返回true表示拦截,那么意思说自己要处理,就传给自己的onTouchEvent处理,线路4:onInterceptTouchEvent 默认或者返回false那么就交给子view的dispatchTouchEvent

6.这个时候有人可能会有疑问,子view没有onInterceptTouchEvent ,那么怎么给它的onTouchEvent呢,为了让View可以把事件分发给自己的onTouchEvent,View的dispatchTouchEvent默认实现(super)就是把事件分发给自己的onTouchEvent

*************************************************************************************************************************8

关于ACTION_MOVE 和 ACTION_UP

 
上面讲解的都是针对ACTION_DOWN的事件传递,ACTION_MOVE和ACTION_UP在传递的过程中并不是和ACTION_DOWN 一样,
你在执行ACTION_DOWN的时候返回了false,后面一系列其它的action就不会再得到执行了。简单的说,就是当dispatchTouchEvent在进行事件分发的时候,
只有前一个事件(如ACTION_DOWN)返回true,才会收到ACTION_MOVE和ACTION_UP的事件。

对于ACTION_MOVE、ACTION_UP总结:ACTION_DOWN事件在哪个控件消费了(return true),
那么ACTION_MOVE和ACTION_UP就会从上往下(通过dispatchTouchEvent)做事件分发往下传,就只会传到这个控件,不会继续往下传,
如果ACTION_DOWN事件是在dispatchTouchEvent消费,那么事件到此为止停止传递,如果ACTION_DOWN事件是在onTouchEvent消费的,
那么会把ACTION_MOVE或ACTION_UP事件传给该控件的onTouchEvent处理并结束传递。
 
 理解自:http://www.jianshu.com/p/e99b5e8bd67b,
http://blog.csdn.net/guolin_blog/article/details/9097463

Android事件分发理解的更多相关文章

  1. 通俗理解Android事件分发与消费机制

    深入:Android Touch事件传递机制全面解析(从WMS到View树) 通俗理解Android事件分发与消费机制 说起Android滑动冲突,是个很常见的场景,比如SliddingMenu与Li ...

  2. [转]Android事件分发机制完全解析,带你从源码的角度彻底理解(上)

    Android事件分发机制 该篇文章出处:http://blog.csdn.net/guolin_blog/article/details/9097463 其实我一直准备写一篇关于Android事件分 ...

  3. 【转】Android事件分发机制完全解析,带你从源码的角度彻底理解(下)

    转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/9153761 记得在前面的文章中,我带大家一起从源码的角度分析了Android中Vi ...

  4. Android事件分发机制浅谈(一)

    ---恢复内容开始--- 一.是什么 我们首先要了解什么是事件分发,通俗的讲就是,当一个触摸事件发生的时候,从一个窗口到一个视图,再到一个视图,直至被消费的过程. 二.做什么 在深入学习android ...

  5. Android事件分发机制(下)

    这篇文章继续讨论Android事件分发机制,首先我们来探讨一下,什么是ViewGroup?它和普通的View有什么区别? 顾名思义,ViewGroup就是一组View的集合,它包含很多的子View和子 ...

  6. Android事件分发机制(上)

    Android事件分发机制这个问题不止一个人问过我,每次我的回答都显得模拟两可,是因为自己一直对这个没有很好的理解,趁现在比较闲对这个做一点总结 举个例子: 你当前有一个非常简单的项目,只有一个Act ...

  7. Android事件分发机制源码分析

    Android事件分发机制源码分析 Android事件分发机制源码分析 Part1事件来源以及传递顺序 Activity分发事件源码 PhoneWindow分发事件源码 小结 Part2ViewGro ...

  8. 【自己定义控件】android事件分发机制

    自己定义Viewgrou中我们或许会常常碰到这种情况,2个子控件的事件冲突导致滑动没实用了.滑动反应非常慢,点击没用了,要划非常多次才移动一点点等等.或许我们第一反应就是百度,google去搜索下答案 ...

  9. Android 事件分发机制具体解释

    很多其它内容请參照我的个人网站: http://stackvoid.com/ 网上非常多关于Android事件分发机制的解释,大多数描写叙述的都不够清晰,没有吧来龙去脉搞清晰,本文将带你从Touch事 ...

随机推荐

  1. React之组件通信

    组件通信无外乎,下面这三种父子组件,子父组件,平行组件(也叫兄弟组件)间的数据传输.下面我们来分别说一下: 父子组件: var Demo=React.createClass({ getInitialS ...

  2. C语言之变量和数据类型

    常量:程序在运行过程中无法对值进行更改. 变量:是在计算机内存空间一种表示,声明变量将会向计算机内存申请存储空间,用于保存数据,计算机的CPU会从内存中加载数据. 声明变量: 数据类型  变量名[=值 ...

  3. java基础(八章)

    一.        什么是数组及其作用? 定义:具有相同数据类型的一个集合 作用:存储连续的具有相同类型的数据 二.        java中如何声明和定义数组 l  声明和定义的语法: 数据类型[ ...

  4. 安装JDK,配置环境变量有感

    前天无事,心血来潮给公司新配的笔记本(win10系统64位)装开发工具,然后不可避免的就装了JDK,顺理成章的需要配置环境变量,结果就出问题了. 配置完成,测试时,在dos命令窗口输入java命令执行 ...

  5. Ipython 自动重载

    一. 使用示例 In [1]: %load_ext autoreload In [2]: %autoreload 2 # Reload all modules (except those exclud ...

  6. [USACO15JAN]电影移动Moovie Mooving

    [USACO15JAN]电影移动Moovie Mooving 时间限制: 2 Sec  内存限制: 128 MB 题目描述 Bessie is out at the movies. Being mis ...

  7. 【解决】VS2013 + Qt 5.7(5.6适用)使用QSqlDatabase出现“无法解析的外部符号"错误

    原始日期: 2016-08-03 22:09  错误如下: error LNK2019: 无法解析的外部符号 "__declspec(dllimport) public: __thiscal ...

  8. 怎么用jq封装插件

    怎么用jq封装插件 以隔行变色为例 实现原理:1.找到表格的奇偶行,然后添加不同的class,激活行高亮显示也很简单,只要判断mouseover事件,然后添加一个class,mouseout的时候,再 ...

  9. 避免循环做SQL操作

    经常犯的错误是把一个SQL 操作放置到一个循环中, 这就导致频繁的访问数据库,更重要的是, 这会直接导致脚本的性能低下.以下的例子, 你能够把一个循环操作重置为一个单一的SQL语句. foreach ...

  10. [leetcode-599-Minimum Index Sum of Two Lists]

    Suppose Andy and Doris want to choose a restaurant for dinner, and they both have a list of favorite ...