整个触摸事件牵涉到的是,Activity,View,ViewGroup三者的传递机制。

这个触摸事件就是从外层往内层一层层的传递。

整个传递机制,分为3个步骤:分发,拦截,和消费。

1. 触摸事件的类型

事件类型是MotionEvent类:看下最新的sdk29的源码,一堆的Action,我们常用的其实就3个,ACTION_DOWN,ACTION_MOVE,ACTION_UP。

Down和Up事件,是触摸过程中一定会发生的事件。Move事件看具体的情况。

2.事件传递的顺序

从外层往内层一层层的传递,外层是那个,内层是那个?

我们从android系统的角度看。事件首先传给的肯定是Activity,因为Activity的UI布局,事物逻辑,作为底层来说,不知道,也并不关心。

所以只要把事件送到Activity层,就可以。

同样的道理,事件先送到ViewGroup,然后在送到View。这样从外层到内层的过程。

其实每一层都会对触摸事件有响应,这个事件是有具体的业务逻辑决定的,所以我们需要一些操作来控制这个事件的过程。

比如点击事件,假设点击了某个按钮,这样它的父ViewGroup要不要处理,页面要不要处理,从表面来看他们都被点击了,从实际人们的经验来看,

就是View被点击了,不需要ViewGroup和Activtiy后面2个事件触发。

Activity->ViewGroup->ViewGroup...->View 整个事件流程传递就是这样。

View->ViewGroup...->ViewGroup->Activity 这个就是事件的消费过程。

3.事件传递的3个阶段

所以android把触摸事件传递分为3个步骤:分发,拦截,和消费。

3.1 分发

分发:事件分发对应着dispatchTouchEvent方法,在Android中,所有的触摸事件都是这个方法来分发的。

public boolean dispatchTouchEvent(MotionEvent ev)

3.1.1 Activity分发

分发是触摸事件首先到达。

  • 返回true,表示事件被消耗掉。不需要分发下去。消费了事件,后续的事件会继续传递到这里。
  • 返回false,表示事件被废弃掉。因为dispatchTouchEvent是总入口,所以就算是false,后续事件还会出现。
  • 返回值是super.dispatchTouchEvent,事件继续传递下去,这个是整个事件传递的中枢,从源码看,一切从这来开始,也从这里结束。

    如果view hierarchy都不处理这个touch事件,就由Activity的onTouch事件来处理。可见上面第二节的结论是正确的。最先接收,最后处理。
/**
* Called to process touch screen events. You can override this to
* intercept all touch screen events before they are dispatched to the
* window. Be sure to call this implementation for touch screen events
* that should be handled normally.
*
* @param ev The touch screen event.
*
* @return boolean Return true if this event was consumed.
*/
public boolean dispatchTouchEvent(MotionEvent ev) {
if (ev.getAction() == MotionEvent.ACTION_DOWN) {
onUserInteraction();
}
if (getWindow().superDispatchTouchEvent(ev)) {
return true;
}
return onTouchEvent(ev);
}

3.1.2VIewGroup分发

  • 返回true,表示事件被消耗掉。不需要分发下去。消费了事件,后续的事件会继续传递到这里。
  • 返回false,表示事件被废弃掉。后续的其他事件不会被传递到这里。
  • 返回值是super.dispatchTouchEvent,事件继续传递下去,这个是整个事件传递的中枢,从源码看,ViewGroup的分发流程分以下几步

    有拦截,拦截了touch事件,就走ViewGroup自己的onTouchEvent。

    没有拦截,就找到触摸点的位置,上面是否有View,有就调view.dispatchTouchEvent,如果没有,就直接交给ViewGroup处理。

    这里还有一点,如果action_down已经处理了,后面action_up 和 action_move都使用相同的处理方式。

3.1.3 View的分发

View的分发,也许会觉得奇怪,分发给谁?

从源码看,2个途径,onTouch listener,或者onTouchEvent。前者优先级必后者高。

  • 返回true,表示事件被消耗掉。不需要分发下去。消费了事件,后续的事件会继续传递到这里。并且这里会认为事件被View消费掉了,所以上层的VIewGroup不会收到要处理onTouchEvent的事件。
  • 返回false,表示事件被废弃掉。后续的其他事件不会被传递到这里。而且可以理解为,我这个View不想处理这个事件,所以ViewGroup会触发onTouchEvent事件。
  • 返回值是super.dispatchTouchEvent
            ListenerInfo li = mListenerInfo;
if (li != null && li.mOnTouchListener != null
&& (mViewFlags & ENABLED_MASK) == ENABLED
&& li.mOnTouchListener.onTouch(this, event)) {
result = true;
} if (!result && onTouchEvent(event)) {
result = true;
}

onTouch是否处理,return true,就表面被第三方处理了,不需要onTouchEvent来处理。不然就是onTouchEvent处理。

3.2 拦截

事件拦截对应onInterceptTouchEvent。事件是从外向内传递的,当事件在分发的过程中,要不要拦截,

public boolean onInterceptTouchEvent(MotionEvent ev)

有些情况下需要子View来响应,有些情况需要当前ViewGroup来处理。这个方法Activity没有,只有ViewGroup才有。

这个简单来说就是,是否需要分发事件给到子View,true就是不分发。

3.3 消费

其实dispatchTouchEvent也有消费的概念在里面。

如果说分发的流程,是从外层到内层,

消费的流程正好相反,从内层到外层。

public boolean onTouchEvent(MotionEvent event)
  • 返回true,消费事件,不在向外层传递

    -返回false,不消费事件,向外层传递

    -返回spuer.onTouchEvent,这里会判断是否是click事件。只有这个写法才会触发click事件。

4. 流程图

5.总结

流程很复杂,每个部分返回不同的true/fase/super都会产生不同的流程结果。

事件分发流程:

从外层到内层分发,

从内层到外层消费。

dispatchTouchEvent 和onTouchEvent,返回true,代表由自己处理这个事情。阻断后面的流程。

dispatchTouchEvent 和onTouchEvent,返回false,表示不由自己来处理这个事件,流程交由上一层级来处理。

dispatchTouchEvent 和onTouchEvent,返回spuer,就是上面的流程。

更多内容:demanmath

公共号:

Android触摸事件传递机制,这一篇就够了的更多相关文章

  1. Android触摸事件传递机制

    简单梳理一下Android触摸事件传递机制的知识点. 一.View与ViewGroup的关系 View和ViewGroup二者的继承关系如下图所示: View是Android中最基本的一种UI组件,它 ...

  2. 初识Android触摸事件传递机制

    前言 今天总结的一个知识点是Andorid中View事件传递机制,也是核心知识点,相信很多开发者在面对这个问题时候会觉得困惑,另外,View的另外一个难题滑动冲突,比如在ScrollView中嵌套Li ...

  3. Android Touch事件传递机制引发的血案

    尊重原创:http://blog.csdn.net/yuanzeyao/article/details/38942135 关于Android Touch事件传递机制我之前也写过两篇文章,自觉得对Tou ...

  4. Android touch 事件传递机制

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

  5. iOS 和 Android 触摸事件传递

    先看文章,写得很好 ios 触摸事件传递 http://www.cnblogs.com/Quains/p/3369132.html 另外一篇 http://blog.csdn.net/yongyinm ...

  6. Android 的事件传递机制,详解

    Android 的事件传递机制,详解 前两天和一个朋友聊天的时候.然后说到事件传递机制.然后让我说的时候,忽然发现说的不是非常清楚,事实上Android 的事件传递机制也是知道一些,可是感觉自己知道的 ...

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

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

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

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

  9. 【转】Android TouchEvent事件传递机制

    Android TouchEvent事件传递机制   事件机制参考地址: http://www.cnblogs.com/sunzn/archive/2013/05/10/3064129.html ht ...

随机推荐

  1. 【题解】P4137 Rmq Problem(莫队)

    [题解]P4137 Rmq Problem(莫队) 其实这道题根本就不用离散化! 因为显然有\(mex\)值是\(\le 2\times 10^5\)的,所以对于大于\(2\times 10^5\)的 ...

  2. 洛谷$P$2468 粟粟的书架 $[SDOI2010]$ 主席树

    正解:主席树 解题报告: 传送门! 题目大意是说,给定一个矩形,然后每次会给一个,这个大矩形中的一个小矩形,询问从小矩形中最少选多少个数字能满足它们之和大于等于给定数字$x$ 看起来很神的样子,完全不 ...

  3. [vsCode实践] 实践记录

    [vsCode实践] 实践记录 版权2019.5.1更新 Q1:代码中涉及到操作本地文件时,相对路径总是不对 操作本地文件时,路径方式有两种 相对路径 例如:代码文件所在路径/Users/tp0829 ...

  4. 突破CRUD | 简单优雅的代码生成工具诞生记(万字长文慎入)

    0.学习本文你或许可以收获 1.一个需求从产生.分析到解决的全过程思考2.简单的面向对象分析实践3.UML类图实践4.设计模式的实践应用5.最后收获一款还算不错的代码生成工具实现思路和源代码 本文将从 ...

  5. Ncverilog 仿真quartus generate IP的要点

    Ncverilog 仿真quartus generate IP的要点 最近利用quartus II 生成plll 的IP,利用nclaunch 仿真的时候老是报错, 提示unresolved in w ...

  6. 51nod 1086背包问题V2 (完全背包模板题)

    1086 背包问题 V2 1 秒 131,072 KB 20 分 3 级题 题目描述 有N种物品,每种物品的数量为C1,C2......Cn.从中任选若干件放在容量为W的背包里,每种物品的体积为W1, ...

  7. MySQL之性能优化

    查看执行计划explain     1.1 Explain命令:它可以对select语句进行分析,并输出select执行的详细信息,以对开发人员针对性优化  1.2 Explain的用法:在selec ...

  8. 微信小程序---自定义三级联动

    在开发的很多电商类型的项目中,免不了会遇到三级联动选择地址信息,如果单纯的使用文本框给用户选择,用户体检可能就会差很多.今天我给大家整理了关于小程序开发利用picker-view组件和animatio ...

  9. NOIP2004普及组第3题 FBI树

    /* 1106: NOIP2004普及组第3题 FBI树 时间限制: 1 Sec 内存限制: 128 MB 提交: 10 解决: 9 [提交] [状态] [讨论版] [命题人:外部导入] 题目描述 我 ...

  10. 【Linux】---Linux系统下各种常用命令总结

    在Linux系统下,“万物皆文件”,之所以强调在强调这个概念,是因为很多人已经习惯了win系统下找找点点得那种方式和思维,因此总是会觉得linux系统下很多指令既复杂又难记.其实都是一样得东西,只是w ...