Gest wielodotykowy polega na dotknięciu ekranu wieloma wskaźnikami (palcami) o tej samej nazwie. W tym dokumencie opisujemy, jak wykrywać gesty, które obejmują za pomocą wielu wskaźników.
Śledzenie wielu wskaźników
Gdy w tym samym czasie dotkniesz ekranu kilkoma wskaźnikami, system wygeneruje te zdarzenia dotknięcia:
ACTION_DOWN
: wysyłane, gdy pierwszy wskaźnik dotknie ekranu. Spowoduje to uruchomienie gestu. dane wskaźnika dla tego wskaźnika są zawsze w indeksie0
wMotionEvent
ACTION_POINTER_DOWN
: wysyłane, gdy na ekranie pojawią się dodatkowe wskaźniki po pierwszym. Możesz uzyskać indeks wskaźnika, który spadł za pomocą funkcjigetActionIndex()
ACTION_MOVE
: jest wysyłana, gdy zmiana zachodzi gestem, obejmująca dowolną liczbę i wskaźnikami.ACTION_POINTER_UP
: wysyłane, gdy wskaźnik inny niż główny przesuwa się w górę. Indeks funkcji wskaźnik, który właśnie wzrósł przy użyciugetActionIndex()
.ACTION_UP
: wysyłane, gdy ostatni wskaźnik opuści ekran.ACTION_CANCEL
: wskazuje, że cały gest, w tym wszystkie wskaźniki, został anulowany.
Gesty rozpoczęcia i zakończenia
Gest to seria zdarzeń rozpoczynających się od znaku ACTION_DOWN
wydarzenie i kończące się ciągiem ACTION_UP
lub
Zdarzenie: ACTION_CANCEL
. Jednocześnie jest wykonywany 1 aktywny gest.
Działania W DÓŁ, PRZENIEŚ, W GÓRĘ i ANULUJ mają zastosowanie do całego gestu. Na przykład
zdarzenie z parametrem ACTION_MOVE
może wskazywać na ruch wszystkich wskaźników
w danym momencie.
Śledzenie wskaźników
Aby śledzić poszczególne wskaźniki, używaj indeksu i identyfikatora wskaźnika
pozycji w obrębie MotionEvent
.
- Indeks: wskaźnik sklepów
MotionEvent
. w tablicy. Indeks wskaźnika to jego pozycja w tej linijce . Większość metodMotionEvent
przyjmuje indeks wskaźnika jako parametr, a nie identyfikator wskaźnika. - ID: każdy wskaźnik ma też mapowanie identyfikatorów, trwała w odniesieniu do zdarzeń dotknięcia, co pozwala na śledzenie poszczególnych wskaźników w całym geście.
Pojedyncze wskaźniki pojawiają się w zdarzeniu ruchu w nieokreślonej kolejności. W związku z tym:
indeks wskaźnika może się zmieniać z jednego zdarzenia na kolejne, ale jego identyfikator
jest stały, dopóki wskaźnik pozostanie niezmieniony.
aktywne. Użyj
getPointerId()
pozwoli uzyskać identyfikator wskaźnika na potrzeby śledzenia go we wszystkich kolejnych
zdarzeń ruchu. Następnie w przypadku kolejnych zdarzeń ruchu użyj
findPointerIndex()
aby uzyskać indeks wskaźnika dla danego identyfikatora wskaźnika w danym zdarzeniu ruchu.
Na przykład:
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); ... }
Aby obsługiwać wiele wskaźników dotykowych, możesz buforować wszystkie aktywne wskaźniki za pomocą
ich identyfikatory na indywidualne ACTION_POINTER_DOWN
oraz
Czas wystąpienia zdarzenia ACTION_DOWN
. Usuń wskaźniki z pamięci podręcznej na
jego wydarzenia ACTION_POINTER_UP
i ACTION_UP
. Możesz
te identyfikatory w pamięci podręcznej są przydatne do prawidłowej obsługi innych zdarzeń działań. Dla:
np. podczas przetwarzania zdarzenia ACTION_MOVE
znajdź indeks dla
każdego identyfikatora aktywnego wskaźnika zapisanego w pamięci podręcznej, pobierz współrzędne wskaźnika za pomocą funkcji
getX()
oraz
getY()
a następnie porównać je ze współrzędnymi z pamięci podręcznej
aby zobaczyć, które wskaźniki się przesunęły.
Używaj funkcji getActionIndex()
z:
ACTION_POINTER_UP
i zdarzenia: ACTION_POINTER_DOWN
Nie używaj tej funkcji w przypadku zdarzeń ACTION_MOVE
, ponieważ
zawsze zwraca 0
.
Pobierz działania (MotionEvent
)
Użyj
getActionMasked()
lub wersji zgodności
MotionEventCompat.getActionMasked()
aby pobrać działanie MotionEvent
. W przeciwieństwie do wcześniejszego
getAction()
metoda getActionMasked()
jest przeznaczona do współpracy z wieloma
i wskaźnikami. Zwraca działanie bez indeksów wskaźnika. Działania ze
prawidłowy indeks wskaźnika, użyj funkcji getActionIndex()
, aby zwrócić indeks
wskaźniki powiązane z działaniem, jak widać w tym fragmencie kodu:
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 ""; }
Dodatkowe materiały
Więcej informacji o zdarzeniach wejściowych znajdziesz w tych artykułach: referencje:
- Zdarzenia wejściowe
- Czujniki omówienie
- Utwórz własny wyświetl interaktywny
- Przeciąganie i skalowanie