单点触控
事件表
事件 |
简介 |
ACTION_DOWN |
手指 初次接触到屏幕 时触发。 |
ACTION_MOVE |
手指 在屏幕上滑动 时触发,会多次触发。 |
ACTION_UP |
手指 离开屏幕 时触发。 |
ACTION_CANCEL |
事件 被上层拦截 时触发。 |
ACTION_OUTSIDE |
手指 不在控件区域 时触发 |
方法表
方法 |
简介 |
getAction() |
获取 事件类型 。 |
getX() |
获得 触摸点 在当前View 的 X坐标 。 |
getY() |
获得 触摸点 在当前View 的 Y坐标 。 |
getRawX() |
获得 触摸点 在整个屏幕的 X坐标 。 |
getRawY() |
获得 触摸点 在整个屏幕的 Y坐标 。 |
简单示例
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()){
case MotionEvent.ACTION_DOWN:
// 手指按下
break;
case MotionEvent.ACTION_MOVE:
// 手指移动
break;
case MotionEvent.ACTION_UP:
// 手指抬起
break;
case MotionEvent.ACTION_CANCEL:
// 事件被拦截
break;
case MotionEvent.ACTION_OUTSIDE:
// 超出区域
break;
}
return super.onTouchEvent(event);
}
ACTION_CANCEL
-
触摸事件流程 :
ACTION_DOWN -> ACTION_MOVE -> ACTION_UP
。
-
触摸事件流程中间 :已经接收到
ACTION_DOWN
事件,但是还没有接收到ACTION_UP
事件。
- 子
View
在 触摸事件流程中间 时,父View
拦截了触摸事件,此时子View
会接收到ACTION_CANCEL
事件。
ACTION_OUTSIDE
-
ACTION_OUTSIDE
不是在View
内部滑动到外部的时候产生的。
-
ACTION_OUTSIDE
用于Dialog
这样的特殊窗口,使其能够接收到视图区域外的事件。
- 默认情况下,无法接收到
ACTION_OUTSIDE
,需要设置视图的WindowManager
布局参数的flags
为FLAG_WATCH_OUTSIDE_TOUCH
。
- 除了
Dialog
之外,最可能看到ACTION_OUTSIDE
的场景是 悬浮窗 。
多点触控
简介
- 发生 多点触控 时,最先接收到的 触摸点 作为 主触摸点 ,之后接收到的 触摸点 作为 辅助触摸点 。
触摸点索引 与 触摸点ID
-
单次触摸事件 :
ACTION_DOWN
、ACTION_UP
、ACTION_MOVE
。
-
触摸事件流程 :
ACTION_DOWN -> ACTION_MOVE -> ACTION_UP
。
-
触摸点索引 与 触摸点ID 都是用于标识 触摸点 ,但是:
-
触摸点索引 只保证在 单次触摸事件 有效。
-
触摸点ID 能保证在整个 触摸事件流程 有效。
- 通常使用 触摸点ID 来标识 触摸点 ,而不是 触摸点索引 。
事件表
事件 |
简介 |
ACTION_DOWN |
第一个 手指 初次接触到屏幕 时触发。 |
ACTION_MOVE |
手指 在屏幕上滑动 时触发,会多次触发。 |
ACTION_UP |
最后一个 手指 离开屏幕 时触发。 |
ACTION_POINTER_DOWN |
有其他手指按下( 即按下之前已经有手指在屏幕上 )。 |
ACTION_POINTER_UP |
有其他手指抬起( 即抬起之后仍然有手指在屏幕上 )。 |
方法表
方法 |
简介 |
getActionMasked() |
获取 事件类型 。 |
getActionIndex() |
获取 触摸点索引 。 |
getPointerCount() |
获取 触摸点 个数。 |
getPointerId(int pointerIndex) |
使用 触摸点索引 获取 触摸点ID 。 |
findPointerIndex(int pointerId) |
使用 触摸点ID 获取 触摸点索引 。 |
getX(int pointerIndex) |
获取 触摸点索引 对应的 X坐标 。 |
getY(int pointerIndex) |
获取 触摸点索引 对应的 Y坐标 。 |
getAction()
与 getActionMasked()
-
多点触控 使用
getActionMasked()
来获取 事件类型 。
-
单点触控 使用
getAction()
(或getActionMasked()
)来获取 事件类型 。
移动事件历史
简介
-
移动事件历史 :由于
ACTION_MOVE
事件的产生十分频繁,为了提高性能,会将多个ACTION_MOVE
事件打包放进同一个MotionEvent
中批量处理。
-
单点触控 和 多点触控 都可以用 移动事件历史 。
方法表
事件 |
简介 |
getHistorySize() |
获取 移动事件历史集合 大小。 |
getHistoricalX(int pos) |
获取第pos 个的 移动事件历史 的 X坐标 。 |
getHistoricalY(int pos) |
获取第pos 个的 移动事件历史 的 Y坐标 。 |
getHistoricalX(int pointerIndex, int pos) |
获取 触摸点索引 对应的第pos 个 移动事件历史 的 X坐标 。 |
getHistoricalY(int pointerIndex, int pos) |
获取 触摸点索引 对应的第pos 个 移动事件历史 的 Y坐标 。 |
触摸事件时间
方法 |
简介 |
getDownTime() |
获取手指按下时的时间,单位为 毫秒 。 |
getEventTime() |
获取当前事件发生的时间,单位为 毫秒 。 |
getHistoricalEventTime(int pos) |
获取第pos 个 移动事件历史 发生的时间,单位为 毫秒 。 |
触摸面积 与 触摸压力
简介
-
触摸面积 识别和 触摸压力 识别是需要硬件支持的。
- 目前,大部分设备的屏幕不支持识别 触摸压力 ,但能够大致识别 触摸面积 。
- 大部分设备是使用 触摸面积 来模拟 触摸压力 的。
方法表
方法 |
简介 |
getSize() |
获取 触摸面积 。 |
getSize(int pointerIndex) |
获取 触摸点索引 对应的 触摸面积 。 |
getHistoricalSize(int pos) |
获取第pos 次 移动事件历史 的 触摸面积 。 |
getHistoricalSize(int pointerIndex, int pos) |
获取 触摸点索引 对应的第pos 次 移动事件历史 的 触摸面积 。 |
getPressure() |
获取 触摸压力 。 |
getPressure(int pointerIndex) |
获取 触摸点索引 对应的 触摸压力 。 |
getHistoricalPressure(int pos) |
获取第pos 次 移动事件历史 的 触摸压力 。 |
getHistoricalPressure(int pointerIndex, int pos) |
获取 触摸点索引 对应的第pos 次 移动事件历史 的 触摸压力 。 |
滑动冲突处理
-
RecyclerView
收到了一个ACTION_DOWN
事件,先假定是个点击事件,传递给对应ItemView
,询问ItemView
是否需要这个事件。
- 接着,
RecyclerView
收到一个ACTION_MOVE
事件,且移动的方向和RecyclerView
的可滑动方向一致,此时可以判断这个事件是 滚动事件 ,因此进行 拦截 。
- 因为上层
View
进行了 拦截 ,所以对应的ItemView
会收到一个 ACTION_CANCEL
,并且不会再收到后续事件。
网友评论