Android Touch分发事件机制详解

**********如果你理解起来比较困难,那你可以看看我的东西,一行一行读下去,至少理解肯定没问题*****

这里主要是针对面试的速成知识点:

原文:https://www.jianshu.com/p/38015afcdb58这里写的特别棒

http://www.cnblogs.com/sunzn/archive/2013/05/10/3064129.html

事件分发主要是指对Touch事件的处理,何为Touch事件?

就是我们常说的点击,触摸事件

Touch事件的相关细节被封装成了一个事件对象:

(发生触摸的位置、时间等)MotionEvent对象

概念**********************************************************************************************

###一个定义:那么Touch事件的分发过程,就是指MotionEvent对象的传递,最终由谁来处理的过程;

或者说事件(MotionEvent)传递到某个具体的View & 处理的整个过程

事件传递的过程 = 分发过程

###四种类型:Touch事件类型:

MotionEvent.ACTION_DOWN按下View(所有事件的开始)

MotionEvent.ACTION_UP抬起View(与DOWN对应)

MotionEvent.ACTION_MOVE滑动View

MotionEvent.ACTION_CANCEL结束事件(非人为原因)

一般手机触摸屏幕,再离开屏幕的过程,会出发一系列的Touch事件

一般情况下,事件列都是以DOWN事件开始、UP事件结束,中间有无数的MOVE事件

当一个事件(MotionEvent )产生后,系统需把这个事件传递给一个具体的 View去处理

原理和过程分析:****************************************************************************

###主要三个对象:Activity,ViewGroup,View

事件传递是在Activity,ViewGroup,View之间传递

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

即:1个点击事件发生后,事件先传到Activity、再传到ViewGroup、最终再传到 View

###主要三个方法:

dispatchTouchEvent() 、onInterceptTouchEvent()和onTouchEvent()

三个对象,每个对象里都有dispatchTouchEvent()和onTouchEvent()方法

ViewGroup里多了一个onInterceptTouchEvent()

**********把以下的分析明白就OK了

这里直接教你面试的时候怎么说:

(1)Activity对点击事件的分发机制

首先会先回掉Activity的dispatchTouchEvent方法,最终会交给ViewGroup的

dispatchTouchEvent()处理。

过程:————————————————————————————————————---------------------


getWindow获取window类的对象,指向唯一的实现类Phonewindow对象,然后再调用他

的superDispatchTouchEvent(ev)方法:

里面调用到:

mDecor.superDispatchTouchEvent(event);

mDecor是(DecorView)的实例对象

a. DecorView类是PhoneWindow类的一个内部类

 b. DecorView继承自FrameLayout,是所有界面的父类

 c. FrameLayout是ViewGroup的子类,故DecorView的间接父类 = ViewGroup

// 调用父类的方法 = ViewGroup的dispatchTouchEvent()// 即 将事件传递到ViewGroup去处理

—————————————————————————————————————————————

ViewGroup的dispatchTouchEvent如果返回true,则不会再执行Activty的OnTouchEvent()方法;

ViewGroup的dispatchTouchEvent如果返回false,则继续执行Activty的OnTouchEvent()方法;

OnTouchEvent这个方法是在当Activty上面所有的View都没有接收处理这个事件的时候

而且要求Activity的dispatchTouchEvent返回false super.OnTouchEvent,才会触发

第一种情况:

比如说你的Activity上什么都没有,但是你触摸了屏幕就一定会触发dispatchTouchEvent,如果没有View消费掉事件,那么会继续触发OnTouchEvent()事件

第二种情况:

如果Activty上有一个按钮,给按钮添加一个点击事件,那么这个按钮被点击时会触发Activity的dispatchTouchEvent方法,但是这个事件被Activity中的Button消费掉 了,那么Activity的OnTouchEvent就不会再继续执行了

注意:

如果Activty的dispatchTouchEvent直接返回false或者True,那么OnTouchEvent()和按钮都不会接收到这个事件了

(2)ViewGroup对点击事件的分发机制

再Activity分发事件的里面可以发现ViewGroup的事件分发也是从dispatchTouchEvent开始的,

在ViewGroup的dispatchTouchEvent,ViewGroup每次事件分发时,都需调用onInterceptTouchEvent()询问是否拦截事件,

ViewGroup.onInterceptTouchEvent()

  * 作用:是否拦截事件

  * 说明:

  *    a. 返回true = 拦截,即事件停止往下传递(需手动设置,即复写onInterceptTouchEvent(),从而让其返回true)

  *    b. 返回false = 不拦截(默认)

  */publicbooleanonInterceptTouchEvent(MotionEvent ev){returnfalse;  }

如果没有拦截,通过for循环,遍历了当前ViewGroup下的所有子View

/ 判断当前遍历的View是不是正在点击的View,

从而找到当前被点击的View// 若是,则进入条件判断内部

// 条件判断的内部调用了该View的dispatchTouchEvent()// 即 实现了点击事件从ViewGroup到子View的传递

// 调用子View的dispatchTouchEvent后是有返回值的// 若该控件可点击,那么点击时,dispatchTouchEvent的返回值必定是true,因此会导致条件判断成立// 于是给ViewGroup的dispatchTouchEvent()直接返回了true,即直接跳出// 即把ViewGroup的点击事件拦截掉

如果onInterceptTouchEvent是拦截的状态

那么返回true = 拦截,即事件停止往下传递,由ViewGroup自己的函数OnTouchEvent等等来处理这个事件

(3)View对点击事件的分发机制



总结:

dispatchTouchEvent 和OnTouchEvent的结果一致,返回true代表事件被消费了

有一层的OnTouchEvent返回了true


被消费一定是在OnTouchEvent中消费,就是在哪一层消费的问题

默认是dispatchTouchEvent的调用会一层一层的向下传递,

OnTouchEvent会一层一层向上传递


就是这个意思:

Activity的dispatchTouchEvent 会调用到ViewGroup的dispatchTouchEvent,

ViewGroup的dispatchTouchEvent会调用到View的dispatchTouchEvent对象

如果有一层返回了true都代表事件被消费了


如果都返回false,那么就回掉Activity的OnTouchEvent方法消费

如果ViewGroup层的拦截器返回true代表拦截,那么就是ViewGroup这一层的OnTouchEvent消费事件

如过默认条件下没有拦截,由view处理,就回掉view的OnTouchEvent消费


如果没有传递到view层,那么onclick就不会被触发了

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

推荐阅读更多精彩内容