Android 事件分发,分发机制

1. 基础认知

1.1 事件分发的对象是谁?

答:点击事件(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事件结束,中间有无数的MOVE事件,如下图:

1.2 事件分发的顺序

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

activity返回true时消费事件,viewGroup不再响应事件。

 

 

示意图

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

答:dispatchTouchEvent() 、onInterceptTouchEvent()和onTouchEvent()

activity事件触发顺序:viewGroup->activity

11-29 16:32:42.067 16915-16915/com.administrator.mvpdome E/lgq: Activity=分发===11111111111111
11-29 16:32:42.068 16915-16915/com.administrator.mvpdome E/lgq: viewGroup=分发===ddddddddddddd
11-29 16:32:42.069 16915-16915/com.administrator.mvpdome D/lgq: viewGroup==拦截==iiiiiiiii
11-29 16:32:42.069 16915-16915/com.administrator.mvpdome I/lgq: viewGroup=触摸===tttttttttttttttt

activity事件触发顺序:view->activity

11-29 16:34:32.027 16915-16915/com.administrator.mvpdome E/lgq: Activity=分发===11111111111111
11-29 16:34:32.028 16915-16915/com.administrator.mvpdome E/lgq: Activity=触摸===11111111111111

 

ViewGroup事件触发顺序:view->viewGroup

11-29 15:28:45.515 10978-10978/com.administrator.mvpdome E/lgq: dispatchTouchEvent=分发===ddddddddddddd
11-29 15:28:45.515 10978-10978/com.administrator.mvpdome D/lgq: onInterceptTouchEvent==拦截==iiiiiiiii
11-29 15:28:45.516 10978-10978/com.administrator.mvpdome I/lgq: onTouchEvent=触摸===tttttttttttttttt

ViewGroup事件触发顺序:viewGroup->viewGroup

11-29 15:28:45.515 10978-10978/com.administrator.mvpdome E/lgq: dispatchTouchEvent=分发===ddddddddddddd
11-29 15:28:45.515 10978-10978/com.administrator.mvpdome D/lgq: onInterceptTouchEvent==拦截==iiiiiiiii

1.4 onTouch()和onTouchEvent()的区别

  • 该2个方法都是在View.dispatchTouchEvent()中调用
  • onTouch()优先于onTouchEvent执行;若手动复写在onTouch()中返回true(即 将事件消费掉),将不会再执行onTouchEvent()

 

ViewGroup的dispatchTouchEvent是真正在执行“分发”工作,而View的dispatchTouchEvent方法,并不执行分发工作,或者说它分发的对象就是自己,决定是否把touch事件交给自己处理,而处理的方法,便是onTouchEvent事件,事实上子View的dispatchTouchEvent方法真正执行的代码是这样的

 

ViewGroup的onTouchEvent事件是什么时候处理的呢?当ViewGroup所有的子View都返回false时,onTouchEvent事件便会执行。由于ViewGroup是继承于View的,它其实也是通过调用View的dispatchTouchEvent方法来执行onTouchEvent事件。

 

在目前的情况看来,似乎只要我们把所有的onTouchEvent都返回false,就能保证所有的子控件都响应本次Touch事件了。但必须要说明的是,这里的Touch事件,只限于Acition_Down事件,即触摸按下事件,而Aciton_UP和Action_MOVE却不会执行。事实上,一次完整的Touch事件,应该是由一个Down、一个Up和若干个Move组成的。Down方式通过dispatchTouchEvent分发,分发的目的是为了找到真正需要处理完整Touch请求的View。当某个View或者ViewGroup的onTouchEvent事件返回true时,便表示它是真正要处理这次请求的View,之后的Aciton_UP和Action_MOVE将由它处理。当所有子View的onTouchEvent都返回false时,这次的Touch请求就由根ViewGroup,即Activity自己处理了。

 

展开阅读全文

没有更多推荐了,返回首页