一.基础知识
1.事件分发
发生了一个Touch事件时,将MotionEvent在屏幕上找到一个具体的View处理之。
2.Touch事件
触摸事件,被分发的对象;
当用户触摸屏幕时(View 或 ViewGroup派生的控件),将产生点击Touch事件。
3.MotionEvent
Touch事件的操作(按下、滑动、抬起、取消),位置,时间等封装成一个MotionEvent对象。
事件类型 | 具体动作 |
---|---|
MotionEvent.ACTION_DOWN | 按下View(所有事件的开始) |
MotionEvent.ACTION_UP | 抬起View(与DOWN对应)(事件序列的结束) |
MotionEvent.ACTION_MOVE | 滑动View |
MotionEvent.ACTION_CANCEL | 滑动超出控件边界时 |
4.事件序列
从手指接触屏幕(DOWN事件) 至 手指离开屏幕(UP/CANCEL事件),整个过程产生的一系列事件
5.事件分发的顺序
Activity -> ViewGroup -> View
![]() | ![]() |
---|
6.事件分发的三个核心方法
- dispatchTouchEvent() 事件的传递
- onInterceptTouchEvent() 事件的拦截
- onTouchEvent() 事件的处理
7.上述方法的返回值含义
dispatchTouchEvent():
- True 本层中做消费事件,事件不再继续分发,事件分发结束。
- False 这一层本次不消费事件,事件分发给child.dispatchTouchEvent()
onTouchEvent():
- True 在本层中做消费事件,事件分发结束。
- False 本层不消费事件,传给上一层(父控件)的onTouchEvent()做处理
onInterceptTouchEvent():
- True 本层ViewGroup拦截此事件,传给本层ViewGroup的onTouchEvent()处理
- False(默认) 本ViewGroup不拦截,事件继续分发,给child.dispatchTouchEvent()
二.详解
1.三大方法总述
以下三张神图讲清了源码中 Activity、ViewGroup、View 中事件分发流程。
2.Activity的事件分发流程
3.ViewGroup事件分发流程
4.View的事件分发流程
5.整个事件分发业务流程
三.我的一些理解
1.消费:就是在当前层处理了事件。
2.事件分发机制设计成两部分:事件的派发(dispatch)和事件的处理。派发时自上而下派发,处理时自下而上处理。 dispatch时可因为ViewGroup的拦截提前进入事件的处理环节。
3.可以重写以上三个方法 + onTouch(),修改其返回值(return true),实现对事件分发流程的控制。
对事件分发的拦截,可以重写OnInterceptTouchEvent()和onTouchEvent()。
如 想要在ViewGroup拦截事件,重写ViewGroup.OnInterceptTouchEvent()使其return true,再重写ViewGroup.onTouchEvent(),增加对事件的处理,最后return true。
4.onTouch()先于onTouchEvent()执行,onTouchEvent()中执行onClick()。所以:
- onTouch()执行高于onClick()
- 重写onTouch()使其return true表明事件已消费,不再走事件分发流程,自然也不会执行onTouchEvent()和其中的onClick()
5.一个事件序列中的所有事件 [1DOWN+nMOVE+1*UP] 都只被同一个View处理(消费)。
四.参考文章
必读:
Android事件分发机制详解:史上最全面、最易懂(神文,源码全解析)
Android校招面试指南-事件分发
选读:
Android事件分发机制详解(带demo)
面试:讲讲 Android 的事件分发机制
Android事件分发机制 详解攻略(带源码分析)
View的事件传递及分发机制(带源码分析)