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事件,如下图:
即当一个点击事件(MotionEvent
)产生后,系统需把这个事件传递给一个具体的 View
去处理。
1.2 事件分发的本质
答:将点击事件(MotionEvent)传递到某个具体的View
& 处理的整个过程
即 事件传递的过程 = 分发过程。
1.3 事件在哪些对象之间进行传递?
答:Activity、ViewGroup、View
Android
的UI
界面由Activity
、ViewGroup
、View
及其派生类组成
1.4 事件分发的顺序
即 事件传递的顺序:Activity
-> ViewGroup
-> View
即:1个点击事件发生后,事件先传到
Activity
、再传到ViewGroup
、最终再传到View
1.5 事件分发过程由哪些方法协作完成?
答:dispatchTouchEvent() 、onInterceptTouchEvent()和onTouchEvent()
下文会对这3个方法进行详细介绍
1.6 总结
-
至此,相信大家已经对
Android
的事件分发有了感性的认知 -
下面,我将详细介绍
Android
事件分发机制
2. 事件分发机制 源码分析
===============
- 请谨记:
Android
事件分发流程 = Activity -> ViewGroup -> View
即:1个点击事件发生后,事件先传到
Activity
、再传到ViewGroup
、最终再传到View
- 从上可知,要想充分理解Android分发机制,本质上是要理解:
-
Activity
对点击事件的分发机制 -
ViewGroup
对点击事件的分发机制 -
View
对点击事件的分发机制
- 下面,我将通过源码,全面解析 事件分发机制
即按顺序讲解:
Activity
事件分发机制、ViewGroup
事件分发机制、View
事件分发机制
2.1 Activity的事件分发机制
当一个点击事件发生时,事件最先传到Activity
的dispatchTouchEvent()
进行事件分发
2.1.1 源码分析
/**
- 源码分析:Activity.dispatchTouchEvent()
*/
public boolean dispatchTouchEvent(MotionEvent ev) {
// 一般事件列开始都是DOWN事件 = 按下事件,故此处基本是true
if (ev.getAction() == MotionEvent.ACTION_DOWN) {
onUserInteraction();
// ->>分析1
}
// ->>分析2
if (getWindow().superDispatchTouchEvent(ev)) {
return true;
// 若getWindow().superDispatchTouchEvent(ev)的返回true
// 则Activity.dispatchTouchEvent()就返回true,则方法结束。即 :该点击事件停止往下传递 & 事件传递过程结束
// 否则:继续往下调用Activity.onTouchEvent
}
// ->>分析4
return onTouchEvent(ev);
}
/**
-
分析1:onUserInteraction()
-
作用:实现屏保功能
-
注:
-
a. 该方法为空方法
-
b. 当此activity在栈顶时,触屏点击按home,back,menu键等都会触发此方法
*/
public void onUserInteraction() {
}
// 回到最初的调用原处
/**
-
分析2:getWindow().superDispatchTouchEvent(ev)
-
说明:
-
a. getWindow() = 获取Window类的对象
-
b. Window类是抽象类,其唯一实现类 = PhoneWindow类;即此处的Window类对象 = PhoneWindow类对象
-
c. Window类的superDispatchTouchEvent() = 1个抽象方法,由子类PhoneWindow类实现
*/