Skip to content

Commit 7d37cb7

Browse files
committed
Update
1 parent a8ac3aa commit 7d37cb7

1 file changed

Lines changed: 65 additions & 4 deletions

File tree

CustomView/Advance/[16]MotionEvent.md

Lines changed: 65 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Android MotionEvent 详解
1+
# MotionEvent 详解
22

33
Android MotionEvent 详解,之前用了两篇文章 [事件分发机制原理][customview/dispatch-touchevent-theory][事件分发机制详解][customview/dispatch-touchevent-source] 来讲解事件分发,而作为事件分发主角之一的 MotionEvent 并没有过多的说明,本文就带大家了解 MotionEvent 的相关内容,简要介绍触摸事件,主要包括 单点触控、多点触控、鼠标事件 以及 getAction() 和 getActionMasked() 的区别。
44

@@ -47,8 +47,8 @@ MotionEvent 负责集中处理所有类型设备的输入事件,但是由于
4747

4848
**手指落下(ACTION_DOWN) -> 多次移动(ACTION_MOVE) -> 离开(ACTION_UP)**
4949

50-
> - 本次事例中 ACTION_MOVE 有多次触发。
51-
> - 如果仅仅是单击(手指按下再抬起),不会触发 ACTION_MOVE。
50+
> * 本次事例中 ACTION_MOVE 有多次触发。
51+
> * 如果仅仅是单击(手指按下再抬起),不会触发 ACTION_MOVE。
5252
5353
![单点触摸事件流程](http://ww4.sinaimg.cn/large/005Xtdi2jw1f8oz1704ylg30bo0jqgmx.gif)
5454

@@ -84,6 +84,8 @@ public boolean onTouchEvent(MotionEvent event) {
8484
但其中有两个比较特殊的事件: `ACTION_CANCEL``ACTION_OUTSIDE`
8585
为什么说特殊呢,因为它们是由程序触发而产生的,而且触发条件也非常特殊,通常情况下即便不处理这两个事件也没有什么问题。接下来我们就扒一扒它们的真面目:
8686

87+
88+
8789
### ACTION_CANCEL
8890

8991
**`ACTION_CANCEL` 的触发条件是事件被上层拦截**,然而我们在 [事件分发机制原理][customview/dispatch-touchevent-theory] 一文中了解到当事件被上层 View 拦截的时候,ChildView 是收不到任何事件的,ChildView 收不到任何事件,自然也不会收到 `ACTION_CANCEL` 了,所以说这个 `ACTION_CANCEL` 的正确触发条件并不是这样,那么是什么呢?
@@ -188,6 +190,21 @@ int类型共32位(0x00000000),他们用最低8位(0x000000**ff**)表示事件
188190
**2、单点触控时由于事件数值不变,使用 `getAction()``getActionMasked()` 两个方法都可以。**
189191
**3、使用 getActionIndex() 可以获取到这个index数值。不过请注意,getActionIndex() 只在 down 和 up 时有效,move 时是无效的。**
190192

193+
目前来说获取事件类型使用 `getActionMasked()` 就行了,但是如果一定要编译时兼容古董版本的话,可以考虑使用这样的写法:
194+
195+
```java
196+
final int action = (Build.VERSION.SDK_INT >= Build.VERSION_CODES.FROYO)
197+
? event.getActionMasked()
198+
: event.getAction();
199+
switch (action){
200+
case MotionEvent.ACTION_DOWN:
201+
// TODO
202+
break;
203+
}
204+
```
205+
206+
207+
191208
### PointId
192209

193210
虽然前面刚刚说了一个 actionIndex,可以使用 getActionIndex() 获得,但通过 actionIndex 字面意思知道,这个只表示事件的序号,而且根据其说明文档解释,这个 ActionIndex 只有在手指按下(down)和抬起(up)时是有用的,在移动(move)时是没有用的,事件追踪非常重要的一环就是移动(move),然而它却没卵用,这也太不实在了 ( ̄Д ̄)ノ
@@ -241,6 +258,50 @@ void printSamples(MotionEvent ev) {
241258

242259

243260

261+
## 获取事件发生的时间
262+
263+
获取事件发生的时间。
264+
265+
| 方法 | 简介 |
266+
| ------------------------------- | ------------ |
267+
| getDownTime() | 获取手指按下时的时间。 |
268+
| getEventTime() | 获取当前事件发生的时间。 |
269+
| getHistoricalEventTime(int pos) | 获取历史事件发生的时间。 |
270+
271+
> 1. pos 表示历史数据中的第几个数据。( pos < getHistorySize() )
272+
> 2. 返回值类型为 long,单位是毫秒。
273+
274+
## 获取压力(接触面积大小)
275+
276+
MotionEvent支持获取某些输入设备(手指或触控笔)的与屏幕的接触面积和压力大小,主要有以下方法:
277+
278+
> 描述中使用了手指,触控笔也是一样的。
279+
280+
| 方法 | 简介 |
281+
| ---------------------------------------- | ---------------------------- |
282+
| getSize () | 获取第1个手指与屏幕接触面积的大小 |
283+
| getSize (int pin) | 获取第pin个手指与屏幕接触面积的大小 |
284+
| getHistoricalSize (int pos) | 获取历史数据中第1个手指在第pos次事件中的接触面积 |
285+
| getHistoricalSize (int pin, int pos) | 获取历史数据中第pin个手指在第pos次事件中的接触面积 |
286+
| getPressure () | 获取第一个手指的压力大小 |
287+
| getPressure (int pin) | 获取第pin个手指的压力大小 |
288+
| getHistoricalPressure (int pos) | 获取历史数据中第1个手指在第pos次事件中的压力大小 |
289+
| getHistoricalPressure (int pin, int pos) | 获取历史数据中第pin个手指在第pos次事件中的压力大小 |
290+
291+
> 1. pin 全称是 pointerIndex,表示第几个手指。(pin < getPointerCount() )
292+
> 2. pos 表示历史数据中的第几个数据。( pos < getHistorySize() )
293+
294+
**注意:**
295+
296+
**1、获取接触面积大小和获取压力大小是需要硬件支持的。**
297+
**2、非常不幸的是大部分设备所使用的电容屏不支持压力检测,但能够大致检测出接触面积。**
298+
**3、大部分设备的 `getPressure()` 是使用接触面积来模拟的。**
299+
**4、由于某些未知的原因(可能系统版本和硬件问题),某些设备不支持该方法。**
300+
301+
我用不同的设备对这两个方法进行了测试,然而不同设备测试出来的结果不相同,之后经过我多方查证,发现是系统问题,有的设备上只有 `getSize()` 能用,有的设备上只有 `getPressure()` 能用,而有的则两个都不能用。
302+
303+
**由于获取接触面积和获取压力大小受系统和硬件影响,使用的时候一定要进行数据检测,以防因为设备问题而导致程序出错。**
304+
244305

245306

246307
## 鼠标事件
@@ -304,4 +365,4 @@ void printSamples(MotionEvent ev) {
304365
[customview/CoordinateSystem]: http://www.gcssloop.com/customview/CoordinateSystem "安卓自定义View基础-坐标系"
305366
[customview/CustomViewProcess]: http://www.gcssloop.com/customview/CustomViewProcess "安卓自定义View进阶-分类与流程"
306367
[customview/dispatch-touchevent-theory]: http://www.gcssloop.com/customview/dispatch-touchevent-theory "安卓自定义View进阶-事件分发机制原理"
307-
[customview/dispatch-touchevent-source]: http://www.gcssloop.com/customview/dispatch-touchevent-source "安卓自定义View进阶-事件分发机制详解"
368+
[customview/dispatch-touchevent-source]: http://www.gcssloop.com/customview/dispatch-touchevent-source "安卓自定义View进阶-事件分发机制详解"

0 commit comments

Comments
 (0)