Gestur sentuh terjadi saat pengguna meletakkan satu atau beberapa jari di layar sentuh dan aplikasi Anda menginterpretasikan pola sentuhan ini sebagai gestur. Ada adalah dua fase untuk deteksi gestur:
- Mengumpulkan data peristiwa sentuh.
- Menafsirkan data untuk menentukan apakah data itu memenuhi kriteria untuk {i>gesture <i}yang didukung aplikasi Anda.
Class AndroidX
Contoh dalam dokumen ini menggunakan
GestureDetectorCompat
dan
MotionEventCompat
Google Cloud Platform. Class ini tersedia di AndroidX
Library. Gunakan class AndroidX jika memungkinkan untuk menyediakan kompatibilitas dengan
perangkat sebelumnya.
MotionEventCompat
bukan pengganti untuk
MotionEvent
. Sebaliknya, ia menyediakan metode utilitas statis yang Anda teruskan
MotionEvent
untuk menerima tindakan yang terkait dengannya
peristiwa.
Mengumpulkan data
Ketika pengguna menempatkan satu atau beberapa jari di layar, hal ini memicu
telepon balik
onTouchEvent()
pada tampilan yang menerima peristiwa sentuh. Untuk setiap urutan sentuhan
— seperti posisi, tekanan, ukuran, dan penambahan
jari—yang diidentifikasi sebagai gestur, onTouchEvent()
adalah
beberapa kali diaktifkan.
Gestur dimulai ketika pengguna pertama kali menyentuh layar, berlanjut ketika
melacak posisi jari atau jari pengguna, dan diakhiri dengan
menangkap peristiwa terakhir dari jari terakhir
pengguna yang meninggalkan layar.
Sepanjang interaksi ini, MotionEvent
dikirimkan ke
onTouchEvent()
memberikan detail setiap interaksi. Aplikasi Anda
dapat menggunakan data yang disediakan oleh MotionEvent
untuk menentukan apakah
{i>gesture <i}yang diinginkan.
Menangkap peristiwa sentuhan untuk Aktivitas atau Tampilan
Untuk mencegat peristiwa sentuh dalam Activity
atau
View
, ganti callback onTouchEvent()
.
Cuplikan kode berikut menggunakan
getAction()
untuk mengekstrak tindakan yang dilakukan pengguna dari parameter event
.
Ini memberi Anda data mentah yang
Anda butuhkan untuk menentukan apakah {i>gesture <i}Anda
tentang terjadi.
Kotlin
class MainActivity : Activity() { ... // This example shows an Activity. You can use the same approach if you are // subclassing a View. override fun onTouchEvent(event: MotionEvent): Boolean { return when (event.action) { MotionEvent.ACTION_DOWN -> { Log.d(DEBUG_TAG, "Action was DOWN") true } MotionEvent.ACTION_MOVE -> { Log.d(DEBUG_TAG, "Action was MOVE") true } MotionEvent.ACTION_UP -> { Log.d(DEBUG_TAG, "Action was UP") true } MotionEvent.ACTION_CANCEL -> { Log.d(DEBUG_TAG, "Action was CANCEL") true } MotionEvent.ACTION_OUTSIDE -> { Log.d(DEBUG_TAG, "Movement occurred outside bounds of current screen element") true } else -> super.onTouchEvent(event) } } }
Java
public class MainActivity extends Activity { ... // This example shows an Activity. You can use the same approach if you are // subclassing a View. @Override public boolean onTouchEvent(MotionEvent event){ switch(event.getAction()) { case (MotionEvent.ACTION_DOWN) : Log.d(DEBUG_TAG,"Action was DOWN"); return true; case (MotionEvent.ACTION_MOVE) : Log.d(DEBUG_TAG,"Action was MOVE"); return true; case (MotionEvent.ACTION_UP) : Log.d(DEBUG_TAG,"Action was UP"); return true; case (MotionEvent.ACTION_CANCEL) : Log.d(DEBUG_TAG,"Action was CANCEL"); return true; case (MotionEvent.ACTION_OUTSIDE) : Log.d(DEBUG_TAG,"Movement occurred outside bounds of current screen element"); return true; default : return super.onTouchEvent(event); } }
Kode ini menghasilkan pesan seperti berikut di Logcat saat pengguna mengetuk, sentuhan & menahan, dan menarik:
GESTURES D Action was DOWN GESTURES D Action was UP GESTURES D Action was MOVE
Untuk gestur kustom, Anda dapat melakukan pemrosesan sendiri pada peristiwa ini untuk
menentukan apakah mereka mewakili {i>gesture <i}yang perlu Anda tangani. Namun, jika
aplikasi menggunakan gestur umum, seperti ketuk dua kali, sentuh & terus, ayunkan, dan sebagainya,
Anda dapat memanfaatkan
GestureDetector
. GestureDetector
memudahkan Anda mendeteksi masalah
{i>gesture <i}tanpa harus memproses
peristiwa sentuh individu itu sendiri. Ini adalah
dibahas lebih lanjut di Mendeteksi gestur.
Menangkap peristiwa sentuhan untuk satu tampilan
Sebagai alternatif onTouchEvent()
, Anda dapat melampirkan
View.OnTouchListener
objek ke View
menggunakan atribut
setOnTouchListener()
. Hal ini memungkinkan untuk memproses peristiwa sentuh tanpa membuat subclass
View
yang ada, seperti yang ditunjukkan dalam contoh berikut:
Kotlin
findViewById<View>(R.id.my_view).setOnTouchListener { v, event -> // Respond to touch events. true }
Java
View myView = findViewById(R.id.my_view); myView.setOnTouchListener(new OnTouchListener() { public boolean onTouch(View v, MotionEvent event) { // Respond to touch events. return true; } });
Berhati-hatilah dalam membuat pemroses yang menampilkan false
untuk
Peristiwa ACTION_DOWN
.
Jika Anda melakukannya, pemroses tidak akan dipanggil untuk
ACTION_MOVE
dan
ACTION_UP
urutan
peristiwa. Hal ini karena ACTION_DOWN
adalah titik awal untuk semua
peristiwa sentuh.
Jika Anda membuat tampilan kustom, Anda dapat mengganti
onTouchEvent()
, seperti yang dijelaskan sebelumnya.
Mendeteksi gestur
Android menyediakan class GestureDetector
untuk mendeteksi
{i>gestures.<i} Beberapa {i>gestures <i}yang didukung
antara lain
onDown()
,
onLongPress()
,
dan
onFling()
.
Anda dapat menggunakan GestureDetector
bersama dengan
Metode onTouchEvent()
yang dijelaskan sebelumnya.
Mendeteksi semua gestur yang didukung
Saat Anda membuat instance objek GestureDetectorCompat
, salah satu
parameter yang diperlukan adalah class yang mengimplementasikan
GestureDetector.OnGestureListener
dalam antarmuka berbasis web
yang sederhana. GestureDetector.OnGestureListener
memberi tahu pengguna jika
terjadi peristiwa sentuh tertentu. Untuk memungkinkan
GestureDetector
untuk menerima peristiwa, mengganti tampilan, atau
metode onTouchEvent()
aktivitas dan meneruskan semua peristiwa yang diamati
ke instance detektor.
Dalam cuplikan berikut, nilai hasil true
dari metode
metode on<TouchEvent>
individual menunjukkan bahwa
peristiwa sentuh akan ditangani. Nilai hasil false
akan meneruskan peristiwa ke bawah
melewati tumpukan tampilan sampai sentuhan berhasil ditangani.
Jika Anda menjalankan cuplikan berikut di aplikasi pengujian, Anda dapat mengetahui caranya
tindakan akan dipicu ketika Anda berinteraksi dengan layar sentuh dan apa
konten MotionEvent
adalah untuk setiap peristiwa sentuh. Anda kemudian melihat
berapa banyak data yang dihasilkan untuk interaksi sederhana.
Kotlin
private const val DEBUG_TAG = "Gestures" class MainActivity : Activity(), GestureDetector.OnGestureListener, GestureDetector.OnDoubleTapListener { private lateinit var mDetector: GestureDetectorCompat // Called when the activity is first created. public override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) // Instantiate the gesture detector with the // application context and an implementation of // GestureDetector.OnGestureListener. mDetector = GestureDetectorCompat(this, this) // Set the gesture detector as the double-tap // listener. mDetector.setOnDoubleTapListener(this) } override fun onTouchEvent(event: MotionEvent): Boolean { return if (mDetector.onTouchEvent(event)) { true } else { super.onTouchEvent(event) } } override fun onDown(event: MotionEvent): Boolean { Log.d(DEBUG_TAG, "onDown: $event") return true } override fun onFling( event1: MotionEvent, event2: MotionEvent, velocityX: Float, velocityY: Float ): Boolean { Log.d(DEBUG_TAG, "onFling: $event1 $event2") return true } override fun onLongPress(event: MotionEvent) { Log.d(DEBUG_TAG, "onLongPress: $event") } override fun onScroll( event1: MotionEvent, event2: MotionEvent, distanceX: Float, distanceY: Float ): Boolean { Log.d(DEBUG_TAG, "onScroll: $event1 $event2") return true } override fun onShowPress(event: MotionEvent) { Log.d(DEBUG_TAG, "onShowPress: $event") } override fun onSingleTapUp(event: MotionEvent): Boolean { Log.d(DEBUG_TAG, "onSingleTapUp: $event") return true } override fun onDoubleTap(event: MotionEvent): Boolean { Log.d(DEBUG_TAG, "onDoubleTap: $event") return true } override fun onDoubleTapEvent(event: MotionEvent): Boolean { Log.d(DEBUG_TAG, "onDoubleTapEvent: $event") return true } override fun onSingleTapConfirmed(event: MotionEvent): Boolean { Log.d(DEBUG_TAG, "onSingleTapConfirmed: $event") return true } }
Java
public class MainActivity extends Activity implements GestureDetector.OnGestureListener, GestureDetector.OnDoubleTapListener{ private static final String DEBUG_TAG = "Gestures"; private GestureDetectorCompat mDetector; // Called when the activity is first created. @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // Instantiate the gesture detector with the // application context and an implementation of // GestureDetector.OnGestureListener. mDetector = new GestureDetectorCompat(this,this); // Set the gesture detector as the double-tap // listener. mDetector.setOnDoubleTapListener(this); } @Override public boolean onTouchEvent(MotionEvent event){ if (this.mDetector.onTouchEvent(event)) { return true; } return super.onTouchEvent(event); } @Override public boolean onDown(MotionEvent event) { Log.d(DEBUG_TAG,"onDown: " + event.toString()); return true; } @Override public boolean onFling(MotionEvent event1, MotionEvent event2, float velocityX, float velocityY) { Log.d(DEBUG_TAG, "onFling: " + event1.toString() + event2.toString()); return true; } @Override public void onLongPress(MotionEvent event) { Log.d(DEBUG_TAG, "onLongPress: " + event.toString()); } @Override public boolean onScroll(MotionEvent event1, MotionEvent event2, float distanceX, float distanceY) { Log.d(DEBUG_TAG, "onScroll: " + event1.toString() + event2.toString()); return true; } @Override public void onShowPress(MotionEvent event) { Log.d(DEBUG_TAG, "onShowPress: " + event.toString()); } @Override public boolean onSingleTapUp(MotionEvent event) { Log.d(DEBUG_TAG, "onSingleTapUp: " + event.toString()); return true; } @Override public boolean onDoubleTap(MotionEvent event) { Log.d(DEBUG_TAG, "onDoubleTap: " + event.toString()); return true; } @Override public boolean onDoubleTapEvent(MotionEvent event) { Log.d(DEBUG_TAG, "onDoubleTapEvent: " + event.toString()); return true; } @Override public boolean onSingleTapConfirmed(MotionEvent event) { Log.d(DEBUG_TAG, "onSingleTapConfirmed: " + event.toString()); return true; } }
Mendeteksi subset gestur yang didukung
Jika Anda hanya ingin memproses
beberapa {i>gestures, <i} Anda dapat memperluas
GestureDetector.SimpleOnGestureListener
bukan menerapkan GestureDetector.OnGestureListener
dalam antarmuka berbasis web
yang sederhana.
GestureDetector.SimpleOnGestureListener
menyediakan
implementasi untuk semua
Metode on<TouchEvent>
dengan menampilkan
false
untuk semuanya. Ini memungkinkan Anda mengganti hanya metode yang
yang penting bagi Anda. Misalnya, cuplikan kode berikut membuat class yang memperluas
GestureDetector.SimpleOnGestureListener
dan penggantian
onFling()
dan onDown()
.
Baik Anda menggunakan GestureDetector.OnGestureListener
atau
GestureDetector.SimpleOnGestureListener
, sebaiknya
implementasikan metode onDown()
yang menampilkan true
. Ini
karena semua gestur dimulai dengan pesan onDown()
. Jika Anda
tampilkan false
dari onDown()
, sebagai
GestureDetector.SimpleOnGestureListener
melakukannya secara default, sistem
mengasumsikan Anda ingin mengabaikan sisa {i>gesture <i}dan metode lainnya
GestureDetector.OnGestureListener
tidak dipanggil. Hal ini dapat menyebabkan
masalah tak terduga
di aplikasi Anda. Hanya kembalikan false
dari
onDown()
jika Anda benar-benar ingin mengabaikan seluruh gestur.
Kotlin
private const val DEBUG_TAG = "Gestures" class MainActivity : Activity() { private lateinit var mDetector: GestureDetectorCompat public override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) mDetector = GestureDetectorCompat(this, MyGestureListener()) } override fun onTouchEvent(event: MotionEvent): Boolean { mDetector.onTouchEvent(event) return super.onTouchEvent(event) } private class MyGestureListener : GestureDetector.SimpleOnGestureListener() { override fun onDown(event: MotionEvent): Boolean { Log.d(DEBUG_TAG, "onDown: $event") return true } override fun onFling( event1: MotionEvent, event2: MotionEvent, velocityX: Float, velocityY: Float ): Boolean { Log.d(DEBUG_TAG, "onFling: $event1 $event2") return true } } }
Java
public class MainActivity extends Activity { private GestureDetectorCompat mDetector; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mDetector = new GestureDetectorCompat(this, new MyGestureListener()); } @Override public boolean onTouchEvent(MotionEvent event){ if (this.mDetector.onTouchEvent(event)) { return true; } return super.onTouchEvent(event); } class MyGestureListener extends GestureDetector.SimpleOnGestureListener { private static final String DEBUG_TAG = "Gestures"; @Override public boolean onDown(MotionEvent event) { Log.d(DEBUG_TAG,"onDown: " + event.toString()); return true; } @Override public boolean onFling(MotionEvent event1, MotionEvent event2, float velocityX, float velocityY) { Log.d(DEBUG_TAG, "onFling: " + event1.toString() + event2.toString()); return true; } } }