Çoklu dokunma hareketi, ekrana birden fazla işaretçinin (parmakların) aynı anda dokunmasıdır. Bu dokümanda, birden çok işaretçi içeren hareketlerin nasıl algılanacağı açıklanmaktadır.
Birden fazla işaretçiyi takip edin
Ekrana aynı anda birden fazla işaretçi dokunduğunda sistem aşağıdaki dokunma etkinliklerini oluşturur:
ACTION_DOWN
: İlk işaretçi ekrana dokunduğunda gönderilir. Bu işlem, hareketi başlatır. Bu işaretçinin işaretçi verileri her zamanMotionEvent
için0
dizinindedir.ACTION_POINTER_DOWN
: Ekstra işaretçiler ilkinden sonra ekrana girdiğinde gönderilir. Az önce düşen işaretçinin dizininigetActionIndex()
kullanarak alabilirsiniz.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 yükseldiğinde gönderilir.getActionIndex()
işlevini kullanarak az önce artan işaretçinin dizinini alabilirsiniz.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 belirtir.
Başlangıç ve bitiş hareketleri
Hareket, bir ACTION_DOWN
etkinliğiyle başlayıp ACTION_UP
veya ACTION_CANCEL
etkinliğiyle sona eren bir etkinlik dizisidir. Aynı anda tek bir etkin hareket vardır. AŞAĞI, TAŞI, YUKARI ve İPTAL işlemleri, tüm hareket için geçerli olur. Örneğin, ACTION_MOVE
içeren bir etkinlik, tüm işaretçilerin o anda aşağı doğru bir hareket ettiğini gösterebilir.
İşaretçileri takip edin
MotionEvent
içindeki bağımsız işaretçi konumlarını takip etmek için işaretçinin dizinini ve kimliğini kullanın.
- Dizin:
MotionEvent
, bir dizide işaretçi bilgilerini depolar. Bir işaretçinin dizini, bu dizi içindeki konumudur.MotionEvent
yöntemlerinin çoğu, işaretçi dizinini işaretçi kimliği yerine parametre olarak alır. - Kimlik: Her işaretçi, tek bir işaretçinin hareketin tamamında izlenebilmesi için dokunma etkinliklerinde kalıcı kalan bir kimlik eşlemesi de bulunur.
İşaretçiler tek tek, bir hareket etkinliğinde tanımlanmamış bir sırada görünür. Bu nedenle, işaretçinin dizini bir etkinlikten diğerine değişebilir ancak işaretçinin işaretçi kimliğinin, işaretçi etkin kaldığı sürece sabit kalması garanti edilir. İşaretçiyi bir harekette izleyen tüm hareket etkinliklerinde izlemek amacıyla işaretçi kimliğini almak için getPointerId()
yöntemini kullanın. Ardından, art arda gerçekleşen hareket etkinlikleri için söz konusu hareket etkinliğindeki belirli bir işaretçi kimliğinin işaretçi dizinini almak için findPointerIndex()
yöntemini kullanın.
Ö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 çok temas işaretçisini desteklemek için, kimlikleriyle birlikte tüm etkin işaretçileri kendi ACTION_POINTER_DOWN
ve ACTION_DOWN
etkinlik zamanında önbelleğe alabilirsiniz. Önbelleğinizden ACTION_POINTER_UP
ve ACTION_UP
etkinliklerinde işaretçileri kaldırın. Önbelleğe alınan bu kimlikleri, diğer işlem etkinliklerini doğru şekilde yönetme konusunda işinize yarayabilir. Ö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çi koordinatlarını alın, ardından hangi işaretçilerin hareket ettiğini öğrenmek 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
sonucunu 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 fazla işaretçiyle çalışacak şekilde tasarlanmıştır. İşlem, işaretçi dizinleri olmadan döndürür. Geçerli bir işaretçi dizini olan işlemlerde, aşağıdaki snippet'te gösterildiği gibi işlemle ilişkili işaretçilerin dizinini döndürmek için 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