多点触控手势是指用多个指针(手指)点按屏幕 。本文档介绍了如何检测涉及 多个指针
跟踪多个指针
当多个指针同时点按屏幕时,系统会生成 以下触摸事件:
ACTION_DOWN
: 在第一个指针点按屏幕时发送。这是手势的起点。通过 此指针的指针数据始终位于0
MotionEvent
。ACTION_POINTER_DOWN
: 当额外的指针在第一个指针之后进入屏幕时发送。您可以获取 使用getActionIndex()
。ACTION_MOVE
: 当手势发生更改时发送, 指针。ACTION_POINTER_UP
: 当非主要指针抬起时发送。您可以从 刚刚使用getActionIndex()
抬起的指针。ACTION_UP
: 当最后一个指针离开屏幕时发送。ACTION_CANCEL
: 表示已取消整个手势,包括所有指针。
开始和结束手势
手势是以 ACTION_DOWN
开头的一系列事件
事件,并以 ACTION_UP
或
ACTION_CANCEL
事件。一次只能使用一个手势。通过
向下、移动、向上和取消操作都会应用于整个手势。例如,
包含 ACTION_MOVE
的事件可以指示所有指针的移动
跟踪指针
使用指针的索引和 ID 跟踪各个指针
MotionEvent
内的位置。
- 索引:
MotionEvent
存储指针 信息。指针的索引就是 数组。大多数MotionEvent
方法将指针索引视为 参数,而不是指针 ID。 - ID:每个指针还具有一个 ID 映射,该映射始终保持 在触摸事件之间保持不变,以便跟踪单个指针
各个指针在动作事件中以不确定的顺序出现。因此,
不同事件之间的指针索引可能会发生变化,但指针 ID
只要指针仍保持固定状态,
活动状态。使用
getPointerId()
方法获取指针的 ID,以便在所有后续活动中跟踪指针
手势中的动作事件。然后,对于连续动作事件,请使用
findPointerIndex()
方法获取给定触控点 ID 在相应动作事件中的触控点索引。
例如:
Kotlin
private var mActivePointerId: Int = 0 override fun onTouchEvent(event: MotionEvent): Boolean { ... // Get the pointer ID. mActivePointerId = event.getPointerId(0) // ... Many touch events later... // Use the pointer ID to find the index of the active pointer // and fetch its position. val (x: Float, y: Float) = event.findPointerIndex(mActivePointerId).let { pointerIndex -> // Get the pointer's current position. event.getX(pointerIndex) to event.getY(pointerIndex) } ... }
Java
private int mActivePointerId; public boolean onTouchEvent(MotionEvent event) { ... // Get the pointer ID. mActivePointerId = event.getPointerId(0); // ... Many touch events later... // Use the pointer ID to find the index of the active pointer // and fetch its position. int pointerIndex = event.findPointerIndex(mActivePointerId); // Get the pointer's current position. float x = event.getX(pointerIndex); float y = event.getY(pointerIndex); ... }
如需支持多个触摸指针,您可以使用以下代码缓存所有活动指针:
其个人 ACTION_POINTER_DOWN
处的身份证件资料
ACTION_DOWN
事件时间。从以下位置从缓存中移除指针:
其 ACTION_POINTER_UP
和 ACTION_UP
事件。您可能会
您会发现这些缓存的 ID 有助于正确处理其他操作事件。对于
例如,在处理 ACTION_MOVE
事件时,查找
每个缓存的活动指针 ID,则使用
getX()
和
getY()
函数,然后将这些坐标与缓存的坐标进行比较,
看看哪些指针移动了
将 getActionIndex()
函数与
ACTION_POINTER_UP
和ACTION_POINTER_DOWN
事件
。请勿将此函数与 ACTION_MOVE
事件一起使用,因为
始终返回 0
。
检索 MotionEvent
操作
使用
getActionMasked()
方法或兼容版本
MotionEventCompat.getActionMasked()
用于检索 MotionEvent
的操作。与之前的
getAction()
方法,getActionMasked()
旨在与多种
指针。它会返回没有指针索引的操作。对于包含
有效的触控点索引,使用 getActionIndex()
可返回
与操作关联的指针,如以下代码段所示:
Kotlin
val (xPos: Int, yPos: Int) = MotionEventCompat.getActionMasked(event).let { action -> Log.d(DEBUG_TAG, "The action is ${actionToString(action)}") // Get the index of the pointer associated with the action. MotionEventCompat.getActionIndex(event).let { index -> // The coordinates of the current screen contact, relative to // the responding View or Activity. MotionEventCompat.getX(event, index).toInt() to MotionEventCompat.getY(event, index).toInt() } } if (event.pointerCount > 1) { Log.d(DEBUG_TAG, "Multitouch event") } else { // Single touch event. Log.d(DEBUG_TAG, "Single touch event") } ... // Given an action int, returns a string description. fun actionToString(action: Int): String { return when (action) { MotionEvent.ACTION_DOWN -> "Down" MotionEvent.ACTION_MOVE -> "Move" MotionEvent.ACTION_POINTER_DOWN -> "Pointer Down" MotionEvent.ACTION_UP -> "Up" MotionEvent.ACTION_POINTER_UP -> "Pointer Up" MotionEvent.ACTION_OUTSIDE -> "Outside" MotionEvent.ACTION_CANCEL -> "Cancel" else -> "" } }
Java
int action = MotionEventCompat.getActionMasked(event); // Get the index of the pointer associated with the action. int index = MotionEventCompat.getActionIndex(event); int xPos = -1; int yPos = -1; Log.d(DEBUG_TAG,"The action is " + actionToString(action)); if (event.getPointerCount() > 1) { Log.d(DEBUG_TAG,"Multitouch event"); // The coordinates of the current screen contact, relative to // the responding View or Activity. xPos = (int)MotionEventCompat.getX(event, index); yPos = (int)MotionEventCompat.getY(event, index); } else { // Single touch event. Log.d(DEBUG_TAG,"Single touch event"); xPos = (int)MotionEventCompat.getX(event, index); yPos = (int)MotionEventCompat.getY(event, index); } ... // Given an action int, returns a string description public static String actionToString(int action) { switch (action) { case MotionEvent.ACTION_DOWN: return "Down"; case MotionEvent.ACTION_MOVE: return "Move"; case MotionEvent.ACTION_POINTER_DOWN: return "Pointer Down"; case MotionEvent.ACTION_UP: return "Up"; case MotionEvent.ACTION_POINTER_UP: return "Pointer Up"; case MotionEvent.ACTION_OUTSIDE: return "Outside"; case MotionEvent.ACTION_CANCEL: return "Cancel"; } return ""; }
其他资源
如需详细了解输入事件,请参阅以下内容 参考: