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自己处理了。