事件分发

事件分发的对象是谁?点击事件(Touch事件)

定义:当用户触摸屏幕时(View 或 ViewGroup派生的控件),将产生点击事件(Touch事件)

Touch事件的相关细节(发生触摸的位置、时间等)被封装成MotionEvent对象

事件类型(4种)

事件类型具体动作

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

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

MotionEvent.ACTION_MOVE滑动View

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

特别说明:从手指接触屏幕 至 手指离开屏幕,这个过程产生的一系列事件

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

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

6666 6 6事件分发的本质

将点击事件(MotionEvent)传递到某个具体的View & 处理的整个过程

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

事件在哪些对象之间进行传递?

Activity、ViewGroup、View

Android的UI界面由Activity、ViewGroup、View 及其派生类组成

事件分发的顺序

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

事件分发过程由哪些方法协作完成?

什么是事件分发

通过手指对屏幕的触摸来完成整个交互过程

用户通过屏幕与手机交互的时候,每一次点击,长按,移动等都是一个事件

事件分发机制

某一个事件从屏幕传递各个View,由View来使用这以事件(消费事件)或者忽略

事件分发的对象是谁

系统把事件封装为MotionEvent对象,事件分发的过程就是MotionEvent分发的过程

事件的类型

按下(ACTION_DOWN)手指刚刚接触屏幕的时候手指按下的动作

移动 (ACTION_MOVE) 手指在屏幕上移动的一个动作在ACTION_DOWN之后并且不包括ACTION_DOWN

抬起(ACTION_UP) 表示手指抬起的一个动作

取消(ACTION_CANCEL) 表示事件的取消 举例:

父容器scollView 上有一个button按钮当我们按下button按钮不抬起而是滑动 scollView就会拦截这一个这一个

事件。同时button上也会接收这个事件表示当前这个点击事件已经取消了。、

事件序列

从手指按下屏幕开始,到手指离开屏幕所产生的一系列事件

事件的传递层级

手指无论触摸哪一个按钮或者子View,其实都是触摸到了我们activity之上

Activity---->Window---->DecorView---->ViewGroup---->View

事件传递所涉及到的三个主要对象

activity  ViewGroup View

事件在Activity中传递的流程

dispatchTouchEvent(MotionEvent ev)

onTouchEvent(MotionEvent ev)

事件在调用dispatchTouchEvent()之后在分发的过程当中就会调用到onTouchEvent()

activity事件分发

首先调用activity的 dispatchTouchEvent()如果事件为一个按下事件的话

默认调用onUserInteraction()默认是一个空方法,会在整个事件开始的时候就会被立即调用到,如果我们

没有对这个方法进行重写的话,那么我们就不需关注它。

接下来就会调用getWindow().superDispatchTouchEvent(ev)从这里开始就正式进入了事件

派发的过程,这里事件开始交给activity所附属的Window进行派发,这个方法最终会一直调用

到ViewGroup中的dispatchTouchEvent()

如果getWindow().superDispatchTouchEvent(ev)返回为true那么

activity的dispatchTouchEvent()也返回为true,定义为事件被消费了

事件结束

如果说getWindow().superDispatchTouchEvent(ev)返回为false

就会调用activity.onTouchEvent() 它首先调用Window下的shouldCloseOnTouch()

判断事件是否在可响应的范围之内,activity.onTouchEvent()是返回true否返回false

Activityy.dispatchTouchEvent()返回值就等于activity.onTouchEvent()的返回值

无论返回什么事件都结束

Activity分发到ViewGroup中

dispatchTouchEvent()就会首先被调用到

onInterceptTouchEvent()事件分发的过程中会被调用

返回为true表示当前的ViewGroup会把事件拦截掉不会向下分发

返回为false当前的ViewGroup不会拦截掉这个事件

onTouchEvent()在View Group里面没有这个方法,是来自ViewGroup父类View的方法

ViewGroup让onInterceptTouchEvent()返回为true拦截掉事件 重写onTouchEvent()此方法处理触摸事件

ViewGroup事件流程

ViewGroup.dispatchTouchEvent()

主要做三件事

1去判断是否需要去拦截事件

2在当前的ViewGroup中找到用户真正触摸的子view

3分发事件到子View上                 

事件从ViewGroup.dispatchTouchEvent()进入

调用onFilterTouchEventForSecurity() 判断触摸事件是否符合安全策略

什么是安全策略:

如果用户点击的View 不在视图顶部 并且设置了当前View不在视图顶部不响应触摸事件,是不会响应我们的触摸事件的。

安全返回为true继续向下执行 不安全返回false事件未消费 结束分发

继续调用onInterceptTouchEvent() 对事件进行拦截处理 如果返回为true

表示拦截此事件不允许事件向子View传递 调用父类的(View)的dispatchTouchEvent()

自己处理该事件

返回为false 允许事件向子View 进行传递找到被点击的子View调用子View的dispatchTouchEvent()

ViewGroup事件结束

ViewGroup分发到View中

dispatchTouchEvent() 标志事件进入到view中了

onTouchEvent() 用户处理触摸事件的逻辑写在次方法中

流程

首先通过dispatchTouchEvent()进入

然后判断这个事件是否具有一个可响应的焦点 返回为false表示view不可响应

事件结束未被消费 返回为true事件继续执行

调用onFilterTouchEventForSecurity() 判断触摸事件是否符合安全策略 符合继续执行 不符合事件结束事件未被消费

继续判断是否是一个鼠标事件 如果为一个鼠标事件 直接返回为true 标志事件被消费了事件结束

继续判断view是否设置了touchListener触摸事件的监听 并且监听listener 中实现的onTouch()的返回值

如果返回值为true表示事件被消费 事件结束 返回值为false表示事件未被消费继续执行

监听view 中onTouchEvent()方法中的返回值 返回值为true事件被消费事件结束 返回值为false标志着最终我们的事件没有被消费

验证事件整个分发流程事件没有被拦截且子view没有消费此事件

Activity dispatchTouchEvent()=======>ViewGroup dispatchTouchEvent()=======>ViewGroup onInterceptTouchEvent()没有拦截

=======>View  dispatchTouchEvent()=======>View onTouchEvent()没有消费=======>ViewGroup onTouchEvent()没有消费=======>

Activity  onTouchEvent()结束                         

并且如果是同一个事件序列  子View或ViewGroup没有消费该事件后续事件就不会再分发到子View中。就会出现如下结果:

Activity dispatchTouchEvent()=======>Activity  onTouchEvent()结束

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

推荐阅读更多精彩内容