android事件分发机制_具体的日志分析

事件分发在android开发中是一个让人头疼的问题,也是在面试过程中问的比较多的一个问题。同样如果能了解事件分发的过程,将有利于我们处理在开发过程中遇到的组件间滑动问题。所以这个也是在复习的时候重点要看的知识点。在准备这篇文章资料的时候我也在草稿纸上画了几次流程,但是总感觉没有《图解 Android 事件分发机制》作者的流程图画的好,所以文章中的流程图就抄了这位作者的流程图(汗颜)。

项目源码

目录

  • 事件类型
  • 事件分发过程及顺序
  • 分发的三个阶段
  • 日志分析
image

1. 事件类型

当我们的手接触与屏幕接触得时候会产生一系列事件,我们可以通过MotionEvent这个类来得到事件的类型。常用的事件类型分为三种:

  • ACTION_DOWNN: 手指刚触摸屏幕,标志着触摸事件的开始

  • ACTION_MOVE: 手指在屏幕上移动

  • ACTION_UP: 手指从屏幕上抬起,标志着事件的结束

在正常的情况下,我们和手机交互会触发一些列的事件发生,例如点击事件会触发ACTION_DOWNN-->ACTION_MOVE,还有滑动事件会触发ACTION_DOWNN-->ACTION_MOVE-->ACTION_UP

2. 事件分发过程及顺序

事件分发过程: 事件的传递我们可以从点击事件来分析,点击事件触发后,系统把这个事件一层层分发,最终传递到具体的view中处理,这个事件的传递过程就是事件的分发过程。

事件的传递顺序是: Activity-->ViewGroup-->View

3. 分发的三个阶段

在研究事件分发的时候可结合上面的流程图

dispatchTouchEvent

分发事件阶段

这个事件可以分几种情况处理:

Activity中的处理

  • Activity中该方法不管返回true或者false事件都会被消耗,事件将不会在传播。
  • 返回父类同名方法:即super.dispatchTouchEvent(ev),那么事件将会继续传播

ViewGroup的处理

  • 返回true:事件被消耗,将不再被传播。
  • 返回false,事件将会回传,调用Activity的onTouchEvent方法。
  • 父类同名方法:将事件分发给自己的onInterceptTouchEvent方法

View中的处理

  • 返回的是false或者父类的同名方法,事件将会回传。事件会回传给给自己的父容器的onTouchEvent来处理。
  • 返回true:事件被消耗,不再传播。

onInterceptTouchEvent

拦截事件,只有ViewGroup才有这个事件。

  • 返回是false或者父类的同名方法,都代表不拦截这个事件,事件将传递给自己的子View中
  • 返回true:表示拦截该事件。调用自己的onTouchEvent来处理这个事件。

onTouchEvent

消耗事件阶段

这个事件也分下面几种情况处理

Activity中的处理

  • 不管这个方法返回的是false、true、或者父类的同名方法,事件都将在这个方法中被处理。事件能传播道这里,就说明这个窗口的ViewGroup和View都没有处理这个事件。

ViewGroup中的处理

  • 返回为false或者父类同名方法:代表它也不处理,事件将会回传给Activity的onTouchEvent来处理。后续的事件也将不再传递给他。

  • 返回true:事件被消耗不会再回传。后续事件将交给他处理,不再传递给它的子View

View中的处理

  • 返回为false或者父类同名方法:代表它不处理,事件将会回传给它的父容器的onTouchEvent来处理。后续的事件也将不再传递给他。

  • 返回true:事件被消耗不会再回传,后续事件将会继续传递给它处理。

4. 日志分析:

下面的所有日志信息可在GitHub的测试项目doc文件夹中的Android事件分发日志信息文件中查看到。

正常情况下日志信息(Activity、ViewGroup、View返回的都是父类同名方法)

View、ViewGroup以及Activity的onTouchEvent返回同名父类或者false的日志信息和下面的相同(Activity返回true也相同),所以就不在文章中粘出来了。

image

从上面的日志信息我们可以看到,当我们点击屏幕的个View的时候,事件先从EventActivity的dispatchTouchEvent分发给TestFrameLayout的dispatchTouchEvent然后在分发到TestView的dispatchTouchEvent中(提前是onInterceptTouchEvent没有拦截)最终交给了TestView的onTouchEvent方法。前文提到过,如果View的onTouch返回为false或者是父类的同名方法,将代表其不处理这个事件,那么事件将会回传。从上面的日志信息我们也能看出来,DOWN事件有被回传给TestFrameLayout的onTouchEvent处理。TestFrameLayout也是返回父类的同名方法,事件将继续回传最后回传到了EventActivity的onTouchEvent中吃力。另外我们从上面的信息中也可以看出,后面的UP事件也没有再向下分发,而是继续交给了Activity的onTouchEvent处理了。

View的onTouchEvent返回true的日志信息

当View的onTouch返回true的时候,代表要处理这个事件。这个事件就不会再回传,后续事件也将会交给他处理。可以分析下面红框的信息

image

当ViewGroup的onTouchEvent返回true时的日志信息

下面红色框为子控件日志信息,事件分发给ViewGroup的子组件TestView,但是它没有处理,事件回传给ViewGroup(黄色框中的日志),它的onTouchEvent返回true,代表事件被他消耗了,后续的事件也将分发给他处理。


image

当onInterceptTouchEvent返回true的日志信息

该方法如果返回为true,表示拦截,事件将交给TestFrameLayout自身的onTouchEvent处理(也就是最后事件消耗或者不消耗,都要看ViewGroup的onTouchEvent怎么处理了)。从下的日志信息中我们看到TestView的onTouchEvent方法并没有调用可以看出。


image

dispatchTouchEvent 返回true日志

注:下面给出的是ViewGroup的日志信息,View的该返回返回的信息和这个差不多,他们两个区别是View将事件传递给ViewGroup的dispatchTouchEvent,而ViewGroup将事件传递给的是Activity的dispatchTouchEvent方法中。因此由于篇幅原因,这里就粘出View的日志信息了。

如果dispatchTouchEvent返回true则代表事件被消耗,事件将不会在向下分发。后续事件将交给他处理。(View同理)


image

dispatchTouchEvent 返回false

如果dispatchTouchEvent返回false,事件也将不会在向下分发,事件将会回传给他上级的onTouchEvent方法中。后续事件将交给他的上级处理处理。(View同理)

image

终结

想要真正搞清楚事件分发,还是要亲自写个demo测试才能容易搞明白,这篇文章个人感觉写的还是有点乱(表达水平有限,嘿嘿)!如果看完了这篇文章不知道在说什么,可以看一看下面的两个链接,这两个链接算是我看过的讲事件分发的文章中写得计较好两个。推荐先看《图解 Android 事件分发机制》,一定要将作者画的流程图搞清楚。

参考:

图解 Android 事件分发机制

Android事件分发机制详解:史上最全面、最易懂

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,717评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,501评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,311评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,417评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,500评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,538评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,557评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,310评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,759评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,065评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,233评论 1 343
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,909评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,548评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,172评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,420评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,103评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,098评论 2 352

推荐阅读更多精彩内容