標籤:
原文地址:http://android.xsoftlab.net/training/gestures/multi.html
多點觸控是指多個手指同時觸控螢幕幕的情況。這節課主要學習如何檢測多點觸控手勢。
記錄多個觸控點
當多根手指同時觸碰到螢幕時,系統會產生以下觸摸事件:
- ACTION_DOWN -第一個觸碰到螢幕的點。它是手勢的起始事件。這個觸控點的指標資料在MotionEvent對象中的索引總是0。
- ACTION_POINTER_DOWN -除第一個觸控點之外的其它點。這個觸控點的指標資料的索引由getActionIndex()方法返回。
- ACTION_MOVE -螢幕上的手指位置發生變化時。
- ACTION_POINTER_UP -除最開始按下的其它觸控點離開螢幕時。
- ACTION_UP -最後一個觸控點離開螢幕時。
我們可以通過每一個觸控點對應的索或ID來追蹤MotionEvent對象中的每一個觸控點:
- Index: MotionEvent對象將觸控點的相關資訊儲存於一個數組中。每一個觸控點的索引則是這個觸控點在數組中的相對位置。MotionEvent對象的大多數方法都可以使用這些索引來與這些點產生互動。
- ID: 每一個觸控點也含有一個ID映射,這個映射關係在手勢事件的整個生命週期內與相對應的觸控點一直保持相對關係。
每個觸控點的出現順序是不固定的。因此,觸控點的索引可以由事件轉移到下一個索引,但是觸控點的ID始終保持為一個常量。使用getPointerId()方法可以獲得指定觸控點的ID,因此可以在餘下的手勢事件中還可以繼續保持與這個觸控點的聯絡。使用findPointerIndex()方法可以根據指定的ID獲得觸控點的索引:
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);}
擷取事件的活動
使用getActionMasked()方法可以擷取MotionEvent的活動。與getAction()方法不同,getActionMasked()適用於多個觸控點。它會返回正在執行的活動。你可以使用getActionIndex()方法獲得與之相關聯的觸控點的索引。下面的代碼示範了這個過程:
Note: 樣本中使用了MotionEventCompat類。這個類位於支援庫中。你應該使用該類以便提供良好的向後相容性。注意,MotionEventCompat類並不可以替代MotionEvent類。這個類提供了一個實用的靜態方法,可以將MotionEvent對象所關聯的活動提取出來。
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 descriptionpublic 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 "";}
有關多點觸控的更多資訊,可以參見課程Dragging and Scaling.
Android官方開發文檔Training系列課程中文版:手勢處理之多點觸控處理