Gestur multi-kontrol adalah saat beberapa pointer (jari) mengetuk layar di perangkat lain di waktu yang sama. Dokumen ini menjelaskan cara mendeteksi {i>gesture <i}yang melibatkan beberapa pointer.
Melacak beberapa pointer
Jika beberapa pointer mengetuk layar secara bersamaan, sistem akan membuat peristiwa sentuh berikut:
ACTION_DOWN
: yang dikirim ketika pointer pertama mengetuk layar. Langkah ini akan memulai gestur. Tujuan data pointer untuk pointer ini selalu berada pada indeks0
diMotionEvent
.ACTION_POINTER_DOWN
: dikirim ketika pointer tambahan masuk ke layar setelah yang pertama. Anda dapat memperoleh indeks pointer yang baru saja turun menggunakangetActionIndex()
.ACTION_MOVE
: dikirim ketika terjadi perubahan dalam {i>gesture, <i}melibatkan sejumlah pointer.ACTION_POINTER_UP
: dikirim ketika pointer non-primary naik. Anda bisa mendapatkan indeks pointer yang baru saja naik menggunakangetActionIndex()
.ACTION_UP
: dikirim saat {i>pointer<i} terakhir meninggalkan layar.ACTION_CANCEL
: menunjukkan bahwa seluruh gestur, termasuk semua pointer, dibatalkan.
Gestur awal dan akhir
Gestur adalah serangkaian peristiwa yang dimulai dengan ACTION_DOWN
dan diakhiri dengan ACTION_UP
atau
Peristiwa ACTION_CANCEL
. Ada satu gestur aktif pada satu waktu. Tujuan
tindakan KE BAWAH, MOVE, NAIK, dan BATALKAN berlaku untuk seluruh gestur. Sebagai contoh,
peristiwa dengan ACTION_MOVE
dapat menunjukkan gerakan untuk semua pointer
saat itu juga.
Memantau pointer
Menggunakan indeks dan ID pointer untuk melacak setiap pointer
posisi dalam MotionEvent
.
- Indeks:
MotionEvent
menyimpan pointer informasi dalam {i>array.<i} Indeks pointer adalah posisinya di dalam . Sebagian besar metodeMotionEvent
mengambil indeks pointer sebagai parameter, bukan ID pointer. - ID: setiap pointer juga memiliki pemetaan ID yang tetap persisten di seluruh peristiwa sentuh untuk memungkinkan pelacakan setiap pointer di seluruh gestur.
Masing-masing pointer muncul di dalam sebuah peristiwa gerakan dalam urutan yang tidak ditentukan. Dengan demikian,
indeks sebuah {i>pointer<i} bisa berubah dari satu
kejadian ke kejadian berikutnya, tetapi ID pointer
pointer dijamin tetap konstan selama pointer tetap
aktif. Gunakan
getPointerId()
untuk mendapatkan ID pointer untuk melacak pointer di semua
kejadian gerakan dalam sebuah {i>gesture.<i} Kemudian, untuk kejadian gerakan berturut-turut, gunakan
findPointerIndex()
untuk memperoleh indeks pointer untuk ID pointer yang diberikan dalam kejadian gerakan itu.
Contoh:
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); ... }
Untuk mendukung beberapa pointer sentuh, Anda dapat meng-cache semua pointer yang aktif dengan
ID mereka di ACTION_POINTER_DOWN
individu dan
Waktu peristiwa ACTION_DOWN
. Hapus pointer dari cache di
peristiwa ACTION_POINTER_UP
dan ACTION_UP
. Anda mungkin
ID yang di-{i>cache<i} ini berguna untuk menangani peristiwa tindakan lainnya dengan benar. Sebagai
misalnya, saat memproses peristiwa ACTION_MOVE
, temukan indeks untuk
setiap ID pointer aktif yang di-cache, mengambil koordinat pointer menggunakan
getX()
dan
getY()
fungsi, lalu bandingkan koordinat ini
dengan koordinat {i>cache<i} Anda untuk
menemukan {i>pointer<i} mana yang dipindahkan.
Gunakan fungsi getActionIndex()
dengan
Peristiwa ACTION_POINTER_UP
dan ACTION_POINTER_DOWN
saja. Jangan gunakan fungsi ini dengan peristiwa ACTION_MOVE
, karena ini
selalu menampilkan 0
.
Mengambil MotionEvent
tindakan
Gunakan
getActionMasked()
atau versi kompatibilitas
MotionEventCompat.getActionMasked()
untuk mengambil tindakan MotionEvent
. Tidak seperti sebelumnya
getAction()
, getActionMasked()
dirancang agar dapat digunakan dengan beberapa
pointer. Metode ini menampilkan tindakan tanpa indeks pointer. Untuk tindakan dengan
indeks pointer yang valid, gunakan getActionIndex()
untuk mengembalikan indeks
pointer yang terkait dengan tindakan seperti yang ditampilkan dalam cuplikan berikut:
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 ""; }
Referensi lainnya
Untuk informasi selengkapnya terkait peristiwa input, lihat referensi berikut referensi: