多點觸控手勢是指有多個指標 (手指) 輕觸螢幕的位置 本文件說明如何偵測涉及的手勢 以便檢視多個指標
追蹤多個指標
如果有多個指標同時輕觸螢幕,系統會產生多個指標 下列觸控事件:
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); ... }
如要支援多個觸控指標,您可以使用
其 ID 必須位於個別 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 ""; }
其他資源
如要進一步瞭解輸入事件,請參閱以下資源 參考資料: