Çoklu dokunma hareketi, birden fazla işaretçi (parmak) ekrana aynı anda dokunduğunda gerçekleşir. Bu dokümanda, birden fazla işaretçi içeren hareketlerin nasıl algılanacağı açıklanmaktadır.
Birden çok işaretçiyi izleme
Birden fazla işaretçi ekrana aynı anda dokunduğunda sistem aşağıdaki dokunma etkinliklerini oluşturur:
ACTION_DOWN
: ilk işaretçi ekrana dokunduğunda gönderilir. Bu işlem, hareketi başlatır. Bu işaretçi için işaretçi verileri her zamanMotionEvent
içindeki0
dizinindedir.ACTION_POINTER_DOWN
: İlkinden sonra ekrana fazladan işaretçiler girdiğinde gönderilir.getActionIndex()
kullanarak az önce aşağı inen işaretçinin dizinini edinebilirsiniz.ACTION_MOVE
: Herhangi bir sayıda işaretçi içeren bir harekette değişiklik gerçekleştiğinde gönderilir.ACTION_POINTER_UP
: Birincil olmayan işaretçi çıktığında gönderilir.getActionIndex()
kullanarak, az önce yukarı çıkan işaretçinin dizinini edinebilirsiniz.ACTION_UP
: Son işaretçi ekrandan ayrıldığında gönderilir.ACTION_CANCEL
: Tüm işaretçiler dahil olmak üzere hareketin tamamının iptal edildiğini gösterir.
Başlangıç ve bitiş hareketleri
Hareket, bir ACTION_DOWN
etkinliği ile başlayıp ACTION_UP
veya ACTION_CANCEL
etkinliği ile biten bir dizi etkinliktir. Aynı anda tek bir etkin hareket var. AŞAĞI, TAŞI, YUKARI ve İPTAL işlemleri hareketin tamamına uygulanır. Örneğin, ACTION_MOVE
içeren bir etkinlik, o andaki tüm işaretçiler için bir hareketi gösterebilir.
İşaretçileri takip edin
MotionEvent
içindeki işaretçi konumlarını tek tek takip etmek için işaretçinin dizinini ve kimliğini kullanın.
- Dizin:
MotionEvent
, işaretçi bilgilerini bir dizide depolar. İşaretçinin dizini, bu dizideki konumudur.MotionEvent
yöntemlerinin çoğu, işaretçi dizinini işaretçi kimliği yerine parametre olarak alır. - Kimlik: Belirli bir işaretçinin hareket genelinde izlenmesini sağlamak için her işaretçinin dokunma etkinliklerinde kalıcı kalan bir kimlik eşlemesi de vardır.
Bağımsız işaretçiler, bir hareket etkinliğinde tanımlanmamış bir sırada görünür. Bu nedenle, bir işaretçinin dizini bir etkinlikten diğerine değişebilir ancak işaretçi etkin olduğu sürece işaretçinin işaretçi kimliğinin sabit kalması garanti edilir. Bir hareketle sonraki tüm hareket etkinliklerinde işaretçiyi takip etmek için işaretçinin kimliğini almak amacıyla getPointerId()
yöntemini kullanın. Ardından, ardışık hareket etkinlikleri için findPointerIndex()
yöntemini kullanarak söz konusu hareket etkinliğindeki belirli bir işaretçi kimliğinin işaretçi dizinini elde edin.
Örnek:
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); ... }
Birden fazla temas işaretçisini desteklemek için tüm etkin işaretçileri kendi ACTION_POINTER_DOWN
ve ACTION_DOWN
etkinlik zamanlarında kimlikleriyle önbelleğe alabilirsiniz. ACTION_POINTER_UP
ve ACTION_UP
etkinliklerinde işaretçileri önbelleğinizden kaldırın. Önbelleğe alınan bu kimlikleri, diğer işlem etkinliklerini doğru şekilde işleme konusunda yararlı bulabilirsiniz. Örneğin, bir ACTION_MOVE
etkinliğini işlerken önbelleğe alınan her etkin işaretçi kimliğinin dizinini bulun, getX()
ve getY()
işlevlerini kullanarak işaretçinin koordinatlarını alın, ardından hangi işaretçilerin taşındığını bulmak için bu koordinatları önbelleğe alınmış koordinatlarınızla karşılaştırın.
getActionIndex()
işlevini yalnızca ACTION_POINTER_UP
ve ACTION_POINTER_DOWN
etkinlikleriyle kullanın. Her zaman 0
değerini döndürdüğünden, bu işlevi ACTION_MOVE
etkinlikleriyle kullanmayın.
MotionEvent
işlemi al
MotionEvent
işlemini almak için getActionMasked()
yöntemini veya uyumluluk sürümünüMotionEventCompat.getActionMasked()
kullanın. Önceki getAction()
yönteminden farklı olarak getActionMasked()
, birden çok işaretçiyle çalışacak şekilde tasarlanmıştır. İşlemi işaretçi dizinleri olmadan döndürür. Geçerli bir işaretçi dizini olan işlemler için işlemle ilişkili işaretçilerin dizinini aşağıdaki snippet'te gösterildiği gibi döndürmek amacıyla getActionIndex()
kullanın:
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 ""; }
Ek kaynaklar
Giriş etkinlikleriyle ilgili daha fazla bilgi için aşağıdaki referanslara bakın:
- Giriş etkinliklerine genel bakış
- Sensörlere genel bakış
- Özel görünümü etkileşimli hale getirme
- Sürükleme ve ölçeklendirme