Kullanıcı bir veya daha fazla parmağını dokunmatik ekrana koyduğunda ve uygulamanız bu dokunma kalıbını bir hareket olarak yorumladığında bir dokunma hareketi gerçekleşir. Hareket algılama, iki aşamadan oluşur:
- Dokunma etkinliği verileri toplanıyor.
- Verileri yorumlayarak uygulamanızın desteklediği hareketlerle ilgili ölçütleri karşılayıp karşılamadığını belirleme.
AndroidX sınıfları
Bu belgedeki örneklerde GestureDetectorCompat
ve MotionEventCompat
sınıfları kullanılmaktadır. Bu sınıflar AndroidX Kitaplığı'nda bulunur. Önceki cihazlarla uyumluluk sağlamak için mümkünse AndroidX sınıflarını kullanın.
MotionEventCompat
, MotionEvent
sınıfının yerine geçmez. Bunun yerine, söz konusu etkinlikle ilişkili işlemi almak için MotionEvent
nesnenizi iletebileceğiniz statik yardımcı program yöntemleri sağlar.
Veri toplama
Kullanıcı ekrana bir veya daha fazla parmağını yerleştirdiğinde, dokunma etkinliklerini alan görünümde onTouchEvent()
geri çağırma işlevi tetiklenir. onTouchEvent()
, hareket olarak tanımlanan her bir dokunma etkinliği dizisi (ör. konum, basınç, boyut ve başka bir parmağın eklenmesi) için birkaç kez tetiklenir.
Hareket, kullanıcı ekrana ilk dokunduğunda başlar, sistem kullanıcının parmağının veya parmaklarının konumunu
izledikçe devam eder ve kullanıcının son parmağının ekrandan ayrıldığı son etkinliği yakalayarak sona erer.
Bu etkileşim boyunca onTouchEvent()
adresine gönderilen MotionEvent
, her etkileşimin ayrıntılarını sağlar. Uygulamanız, önemsediği bir hareketin gerçekleşip gerçekleşmediğini belirlemek için MotionEvent
tarafından sağlanan verileri kullanabilir.
Bir Aktivite veya Görünüm için dokunma etkinliklerini yakalayın
Activity
veya View
içinde dokunma etkinliklerine müdahale etmek için onTouchEvent()
geri çağırmasını geçersiz kılın.
Aşağıdaki kod snippet'i, kullanıcının event
parametresinden gerçekleştirdiği işlemi ayıklamak için getAction()
kullanır.
Bu, önemsediğiniz bir hareketin gerçekleşip gerçekleşmediğini belirlemeniz için gereken ham verileri sağlar.
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); } }
Bu kod, kullanıcı dokunma, dokunma ve basılı tutma işlemleri sırasında Logcat'te aşağıdakine benzer mesajlar oluşturur:
GESTURES D Action was DOWN GESTURES D Action was UP GESTURES D Action was MOVE
Özel hareketler için bu etkinliklerde kendi işlemenizi yaparak, hareket etmeniz gereken bir hareketi temsil edip etmediğini belirleyebilirsiniz. Bununla birlikte, uygulamanızda iki kez dokunma, dokunup basılı tutma, hızla kaydırma gibi sık kullanılan hareketler kullanılıyorsa GestureDetector
sınıfından yararlanabilirsiniz. GestureDetector
, dokunma etkinliklerini ayrı ayrı işlemenize gerek kalmadan, sık yapılan hareketleri algılamanızı kolaylaştırır. Bu konu Hareketleri algılama bölümünde daha ayrıntılı olarak açıklanmaktadır.
Dokunma etkinliklerini tek bir görünüm için yakalayın
onTouchEvent()
işlevine alternatif olarak, setOnTouchListener()
yöntemini kullanarak herhangi bir View
nesnesine View.OnTouchListener
nesnesi ekleyebilirsiniz. Bu, aşağıdaki örnekte gösterildiği gibi, mevcut bir View
öğesini alt sınıflandırmadan dokunma etkinliklerini dinlemeyi mümkün kılar:
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; } });
ACTION_DOWN
etkinliği için false
değerini döndüren bir işleyici oluşturmaya dikkat edin.
Bunu yaparsanız işleyici, sonraki ACTION_MOVE
ve ACTION_UP
etkinlik dizisi için çağrılmaz. Bunun nedeni, ACTION_DOWN
ürününün tüm dokunma etkinlikleri için başlangıç noktası olmasıdır.
Özel görünüm oluşturuyorsanız daha önce açıklandığı gibi onTouchEvent()
öğesini geçersiz kılabilirsiniz.
Hareketleri algılama
Android, yaygın hareketleri algılamak için GestureDetector
sınıfını sağlar. Desteklediği hareketlerden bazıları şunlardır:
onDown()
,
onLongPress()
ve
onFling()
.
GestureDetector
yöntemini daha önce açıklanan onTouchEvent()
yöntemiyle birlikte kullanabilirsiniz.
Desteklenen tüm hareketleri algıla
Bir GestureDetectorCompat
nesnesini örneklendirdiğinizde gereken parametrelerden biri, GestureDetector.OnGestureListener
arayüzünü uygulayan bir sınıftır. GestureDetector.OnGestureListener
, belirli bir dokunma etkinliği gerçekleştiğinde kullanıcıları bilgilendirir. GestureDetector
nesnenizin etkinlikleri alabilmesini sağlamak için görünümün veya etkinliğin onTouchEvent()
yöntemini geçersiz kılın ve gözlemlenen tüm etkinlikleri algılayıcı örneğine iletin.
Aşağıdaki snippet'te, bağımsız on<TouchEvent>
yöntemlerinden gelen true
değeri, dokunma etkinliğinin işlendiğini gösterir. false
işlevinin döndürülen değeri, dokunma işlemi başarıyla tamamlanana kadar etkinlikleri görünüm yığınından geçirir.
Aşağıdaki snippet'i bir test uygulamasında çalıştırırsanız dokunmatik ekranla etkileşimde bulunduğunuzda işlemlerin nasıl tetiklendiği ve her bir dokunma etkinliği için MotionEvent
içeriğinin neler olduğu konusunda fikir edinebilirsiniz. Daha sonra basit etkileşimler için ne kadar veri oluşturulduğunu görüyorsunuz.
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; } }
Desteklenen hareketlerin bir alt kümesini algıla
Yalnızca birkaç hareketi işlemek istiyorsanız GestureDetector.OnGestureListener
arayüzünü uygulamak yerine GestureDetector.SimpleOnGestureListener
aracını genişletebilirsiniz.
GestureDetector.SimpleOnGestureListener
, tümü için false
döndürerek tüm on<TouchEvent>
yöntemlerine
uygulama sağlar. Bu, yalnızca önem verdiğiniz yöntemleri geçersiz kılmanıza
olanak tanır. Örneğin, aşağıdaki kod snippet'i GestureDetector.SimpleOnGestureListener
öğesini genişleten ve onFling()
ile onDown()
değerlerini geçersiz kılan bir sınıf oluşturur.
İster GestureDetector.OnGestureListener
ister GestureDetector.SimpleOnGestureListener
kullanın, true
döndüren bir onDown()
yöntemi uygulamak en iyi uygulamadır. Bunun nedeni, tüm hareketlerin onDown()
mesajıyla başlamasıdır. GestureDetector.SimpleOnGestureListener
ürününün varsayılan olarak yaptığı gibi onDown()
üzerinden false
değerini döndürürseniz sistem, hareketin geri kalanını yoksaymak istediğinizi varsayar ve GestureDetector.OnGestureListener
öğesinin diğer yöntemleri çağrılmaz. Bu, uygulamanızda beklenmedik
sorunlara neden olabilir. Bir hareketin tamamını gerçekten yoksaymak istiyorsanız
onDown()
uygulamasından yalnızca false
değerini döndürün.
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; } } }