1、概念

Touch事件分发中有三个主角:Activity、ViewGroup和View。Activity的Touch事件事实上是调用它内部的ViewGroup的Touch事件,可以直接当成ViewGroup处理。

View在ViewGroup内,ViewGroup也可以在其他ViewGroup内,这时候把内部的ViewGroup当成View来分析。

View的相关事件只有两个:dispatchTouchEvent、onTouchEvent。ViewGroup的相关的事件在View的基础上则多一个事件onInterceptTouchEvent,只对ViewGroup可响应的事件进行拦截处理。

2、理解模型

整个ViewGroup处理流程,可以看做是Touch事件在以ViewGroup为中间节点的树状结构中寻找响应。

  1. 如果用户执行一个ACTION_DOWN事件,当前View的onInterceptTouchEvent返回true,则该事件和后续的ACTION_MOVE和,ACTION_UP将不再传递到View的子控件,而是直接交由该View的onTouchEvent来处理。
  2. 如果上面onInterceptTouchEvent返回false,则该事件和后续的ACTION_UP,ACTION_MOVE将也会透过onInterceptTouchEvent,继而传递到子控件的onInterceptTouchEvent。
  3. 如果该View的onInterceptTouchEvent返回false,事件传递到目标View,然后目标View的onTouchEvent又返回了false,那么事件将继续传递到目标View的上一级的onTouchEvent。如果目标View的onTouchEvent方法返回了true,说明此事件已被处理了。

3、几条基本规则

1.如果在某个层级没有处理ACTION_DOWN事件,那么该层就再也收不到后续的Touch事件了直到下一次ACTION_DOWN事件。

说明:a.某个层级没有处理某个事件指的是它以及它的子View都没有处理该事件。

b.这条规则不适用于Activity层(它是顶层),它们可以收到每一个Touch事件。

c.如果没有处理ACTION_MOVE这类事件,不会有任何影响。

2.如果ACTION_DOWN事件发生在某个View的范围之内,则后续的ACTION_MOVE,ACTION_UP和ACTION_CANCEL等事件都将被发往该View,即使事件已经出界了。

3.第一根按下的手指触发ACTION_DOWN事件,之后按下的手指触发ACTION_POINTER_DOWN事件,中间起来的手指触发ACTION_POINTER_UP事件,最后起来的手指触发ACTION_UP事件(即使它不是触发ACTION_DOWN事件的那根手指)。

4.pointer id可以用于跟踪手指,从按下的那个时刻起pointer id生效,直至起来的那一刻失效,这之间维持不变。

5.如果一个ACTION_DOWN事件被父View拦截了,则任何子View不会再收到任何Touch事件了(这符合第1点的要求)。

6.如果一个非ACTION_DOWN事件被父View拦截了,则那些上次处理了ACTION_DOWN事件的子View会收到一个ACTION_CANCEL事件,之后不会再收到任何Touch事件了,即使父View不再拦截后续的Touch事件。

7.如果父View决定处理Touch事件或者子View没有处理Touch事件,则父View按照普通View的处理方式处理Touch事件,否则它根本不处理Touch事件(它只负责分发)。

8.如果父View在onInterceptTouchEvent中拦截了事件,则onInterceptTouchEvent中不会再收到Touch事件了,事件被直接交给它自己处理(按照普通View的处理方式)。

4、分层理解

View层:

  View的onTouch方法代码比较多,主要的逻辑分两步:

  1. 先是将事件交给TouchDelegate处理(如果有的话),如果TouchDelegate没有处理再自行处理;
  2. 自行处理主要负责View状态的变换(如按下状态),长按事件,点击事件的检测与触发等。

ViewGroup层:

ViewGroup层处理Touch事件的总体逻辑是:

  1. 先检测是否需要拦截,没有拦截的话下发给子View处理
  2. 如果子View没有处理再自行处理,自行处理的逻辑与View一样

拦截的逻辑是,将从down到up之间的所有事件看作一组事件,如果从down就拦截了,则组内的后续其它事件完全交给自己处理,不需要再进入拦截逻辑了;如果是从中间拦截,则先给子View发送cancel事件,组内的后续其它事件完全交给自己处理,不需要再进入拦截逻辑了。

分发的逻辑是,在ACTION_DOWN事件的时候,寻找子View进行处理,称为寻找Target;如果没有找到Target,则自行处理;如果找到Target,则交由Target处理。

从代码上看,dispatchTouchEvent负责分发逻辑,onTouchEvent负责真正的处理逻辑,一般应该重载onTouchEvent,只有特殊情况下才需要重载dispatchTouchEvent。

5、分发过程

dispatchTouchEvent是负责分发事件的,事件从activity传递出来之后,最先抵达便是最顶层view的dispatchTouchEvent,然后再进行分发,如果返回false,则交给这个view的interceptTouchEvent方法来决定是否要拦截这个事件,

  1. 如果interceptTouchEvent返回true,也就是拦截掉了,则交给它的onTouchEvent来处理,
  2. 如果interceptTouchEvent返回false,那么就传递给子view,由子view的dispatchTouchEvent再来开始这个事件的分发。

6、总结

  Touch事件机制主要有三个重要动作:事件的分发、事件的处理和拦截

  事件的分发是在Activity和ViewGroup中进行,事件的拦截就只能在ViewGroup进行,而事件的处理则可以在三个主体都进行。

http://www.cnblogs.com/frydsh/archive/2012/11/08/2760408.html

http://www.open-open.com/lib/view/open1422428386548.html

http://blog.csdn.net/chenjie19891104/article/details/7014649

http://blog.csdn.net/fastthinking/article/details/21954245

Touch事件机制的更多相关文章

  1. React-Native系列Android——Touch事件原理及状态效果

    Native原生相比于Hybrid或H5最大长处是具有流畅和复杂的交互效果,触摸事件便是当中重要一项,包括点击(Click).长按(LongClick).手势(gesture)等. 以最简单常见的点击 ...

  2. Android Touch事件传递机制 二:单纯的(伪生命周期)

    转载于:http://blog.csdn.net/yuanzeyao/article/details/38025165 在前一篇文章中,我主要讲解了Android源码中的Touch事件的传递过程,现在 ...

  3. Android Touch事件传递机制 一: OnTouch,OnItemClick(监听器),dispatchTouchEvent(伪生命周期)

      ViewGroup View  Activity dispatchTouchEvent 有 有 有 onInterceptTouchEvent 有 无 无 onTouchEvent 有 有 有 例 ...

  4. Android touch 事件传递机制

    前言: (1)在自定义view的时候经常会遇到事件拦截处理,比如在侧滑菜单的时候,我们希望在侧滑菜单里面有listview控件,但是我们希望既能左右滑动又能上下滑动,这个时候就需要对触摸的touch事 ...

  5. Android Touch事件传递机制解析 (推荐)

    最近新闻列表里的下拉 down up  move 等等让我十分头疼 ,无意间看到了一篇非常不错的帖子,转载如下: 开篇语:最近程序在做一个小效果,要用到touch,结果整得云里面雾里的,干脆就好好把a ...

  6. Android Touch事件传递机制解析

    android系统中的每个ViewGroup的子类都具有下面三个和TouchEvent处理密切相关的方法: 1)public boolean dispatchTouchEvent(MotionEven ...

  7. Android Touch事件传递机制通俗讲解

    在讲正题之前我们讲一段有关任务传递的小故事,抛砖迎玉下: 话说一家软件公司,来一个任务,分派给了开发经理去完成: 开发经理拿到,看了一下,感觉好简单,于是 开发经理:分派给了开发组长 开发组长:分派给 ...

  8. (转)Android Touch事件传递机制

    -----来源:http://www.trinea.cn/android/touch-event-delivery-mechanism/ 介绍Android Touch事件的传递机制. 不少朋友私信问 ...

  9. Android Touch事件传递机制具体解释 上

    尊重原创:http://blog.csdn.net/yuanzeyao/article/details/37961997 近期总是遇到关于Android Touch事件的问题,如:滑动冲突的问题,曾经 ...

随机推荐

  1. iOS9 Https技术预研

    一.服务器需要做的事情: 1.要注意 App Transport Security 要求 TLS 1.2, 2.而且它要求站点使用支持forward secrecy协议的密码. 3.证书也要求是符合A ...

  2. Android-图像原理/绘制原理

    图像原理 先专门讲解图片,一想到图片有那些特点:    宽/高 格式jpg/jpeg/... 大小43.kb/... 图片是由像素点组成:像素点是正方形的,只是像素点很小很多,看起来可以拼接圆形⭕️, ...

  3. 结对项目— 词频统计(语言C++)

    结对对象:季天梦 博客地址:http://www.cnblogs.com/jitianmeng/ github链接:https://github.com/liuyutianlyt/EX_4.md 比例 ...

  4. vs的 Avalon 自动补全

    以VS2013为例: 1.关闭 Visual Studio 2.打开 C:/Program Files (x86)/Microsoft Visual Studio 12.0/Common7/Packa ...

  5. 命令行web客户端与HTTP REST API调试工具

    1.命令行web客户端 curl wget httpie 2.优雅的REST API调试工具 insomnia postman

  6. yum初识

    yum仓库中的元数据文件: primary.xml.gz 所有RPM包的列表: 依赖关系: 每个RPM安装生成的文件列表: filelists.xml.gz 当前仓库中所有RPM包的所有文件列表: o ...

  7. C# superGridControl 样式设置、加载数据、获取数据

    样式设置 superGridControl1.PrimaryGrid.SelectionGranularity = SelectionGranularity.Cell; //设置选中样式 单元格.整列 ...

  8. C#Encoding

    1.Encoding (1).如何生成一个Encoding即一种编码 Encoding位于System.Text命名空间下,是一个抽象类,它的派生类如下图: 要实例化一个Encoding一共有以下两种 ...

  9. Sql语法高级应用之一:使用sql语句如何实现不同的角色看到不同的数据

    前言 在常见的管理系统中,通常都有这样的需求,管理员可以看到所有数据,部门可以看到本部门的数据,组长可以看到自己组的数据,组员只能看到自己相关的数据. 一般人的做法是,根据不同的角色通过if...el ...

  10. 决定以后再做公司的项目的时候,能够用其他语言的绝对不用delphi

    1.delphi7的IDE真的很不友好 2.delphi7的控件有的有问题 3.delphi7居然不支持结构体的泛型存储 4.网上的解决文档超少,一些小bug,就要折腾半天 5.pascal语法太过结 ...