2016-09-19 20 views
5

Android uygulamasında dokunma izleme etkinlikleri gerektiren bir sorun var (parmağınızı aşağı/yukarı hareket ettirme, taşıma, yukarı, vb.). Mevcut dokunmanın koordinatlarını almak için event.getX() ve event.getY() işlevlerini kullanmalıyım. Bu yüzden son birkaç ay içinde öğrendiklerinizeAndroid MotionEvent Pointer Dizini Confusion

:

  • MotionEvent.ACTION_DOWN
  • MotionEvent.ACTION_UP kadar
  • MotionEvent.ACTION_POINTER_UP son dokunuş izler aşağı
  • aşağı
  • MotionEvent.ACTION_POINTER_DOWN parça müteakip dokunuşlar ilk dokunuş izler
  • MotionEvent.ACTION_MOVE yukarı giden izler herhangi bir dokunma hareketini izler

Uygulamamda, ilk dokunuşum yükseldiğinde önemli bir sorunla karşılaşıyorum. Cihazımın beş parmağımın dokunulduğuna inanıyorum (bu Touch'a 0, 1, 2, 3, 4'ü arayalım). Şimdi, Touch 0'ı kaldırdığımda, MotionEvent.ACTION_POINTER_UP aldığım işlemdir. Tamamen anlaşılabilir; Bunu anladım. Ancak, şimdi bu iki şey olur:

    Dokunuşlar 1-4 şey taşıyın
  • : Bir IllegalArgumentException pointerIndex aralık dışında bana alın
  • yukarı kaldırın Dokunuşlar 1-4 kadar her şey: bilgileri geri tükürür farklı bir dokunuş (event.getX() ve event.getY() bana farklı parmak bilgi verecektir)

düzgün bu bilgileri izlemek için nasıl benim Zekâ sonuna tür değilim. Bilgileri doğru bir şekilde izleyebilmeniz veya dokunmatik göstergelerinizi nasıl dengeleyeceğiniz hakkında ipuçları var mı?

benim kod ne olduğuna dair genel düzenini sağladı ama sıra dışı bir şey yapmıyorum gibi hissediyorum (ve bunu Android örnekler üzerinde örnek kod yakındır eminim?):

@Override 
public boolean onTouch(View v, MotionEvent event) { 
    int action = event.getActionMasked(); 
    int ptr_idx = event.getPointerId(event.getActionIndex()); 

    try { 
     switch (action) { 
      case MotionEvent.ACTION_MOVE: 
       handleActionPointerMove(event); 
       break; 

      // Order of touch downs doesn't matter to us 
      case MotionEvent.ACTION_DOWN: 
      case MotionEvent.ACTION_POINTER_DOWN: 
       handleActionPointerDown(event, ptr_idx); 
       break; 

      case MotionEvent.ACTION_UP: 
      case MotionEvent.ACTION_POINTER_UP: 
       handleActionPointerUp(event, ptr_idx); 
       break; 
      } 
     } 
     catch (IllegalArgumentException e) { 
      e.printStackTrace(); 
      return false; 
     } 

     return true; 
    } 
} 

public void handleActionPointerMove(MotionEvent event) { 
    for (int i = 0; i < event.getPointerCount(); i++) { 
     handleInformation(event.getX(i), event.getY(i)); 
    } 
} 

public void handleActionPointerDown(MotionEvent event, int ptr_idx) { 
    handleInformation(event.getX(ptr_idx), event.getY(ptr_idx)); 
} 

public void handleActionPointerUp(MotionEvent event, int ptr_idx) { 
    handleInformation(event.getX(ptr_idx), event.getY(ptr_idx)); 
} 

public void handleInformation(int x, int y) { 
    // Figures out what x+y means to us (are we in a certain box within the app? outside in clear zones? etc 
} 

cevap

0

Eh MotionEvent.getX() ve MotionEvent.getY() çağırmadan önce bunu yapmaya çalışmak için ele verdik bir gece düşünmeden sonra:

: döngü deyimi için

public int getAdjustment(int ptr_idx) { 
    int adjust = 0; 
    for (int i = 0; i < event.getPointerCount(); i++) { 
     // Get Actual Pointer Index of touch 
     int adjustedPointerIndex = event.getPointerId(i); 
     // If we've found the current touch's pointer index AND 
     // the pointer index doesn't equal the sequential event's 
     // pointers 
     if ((adjustPointerIndex == ptr_idx) && (i != adjustPointerIndex)) { 
      adjust = (adjustPointerIndex - i); 
      break; 
     } 
    } 

    return adjust; 
} 

// Example Function using getAdjustment(int ptr_idx) 
public void handleActionPointerUp(MotionEvent event, int ptr_idx) { 
    int adjustment = ptr_idx - getAdjustment(ptr_idx); 
    handleInformation(event.getX(adjustment), event.getY(adjustment)); 
} 

Açıklama

Temel olarak, 4 dokunuşumuz olduğunu belirtelim (Dokunma 0, 1, 2, 3). Şimdi Touch 0'ı kaldırdık ve şimdi Touch 1, 2, 3'e sahibiz. Android bu dokunuşları 0, 1, 2 ve gerçek işaretçi indekslerini 1, 2, 3 olarak görecek. Doğru ayarlamayı elde etmek için MotionEvent'un işaretçileri (bu, şu an için döngüde 0, 1, 2'dir).

Bazı nedenlerle 0 ya da aradaki herhangi bir dokunuşun çıkarılması durumunda, işaretçi dizinini getX() olarak ayarlamalı ve getY() dokunmanın gerçek işaretçi dizinini anlamamalıdır. 1, 2, 3 işaretçi indekslerine sahip olmamıza rağmen, sadece 0, 1, 2 indekslerini alır. Böylece, eğer doğru akım dokunmatik işaretçi dizinine ulaşırsak MotionEvent 'un dokunmatik indeksi, doğru işaretçi indeksine eşit değildir. adjust = adjustPointerIndex-i yaparak ayarlıyoruz.

bunu yaparken sonra, sadece biz inceliyoruz güncel ptr_idx onu çıkarmak ve biz getX() ve getY() aralığın dışında bir pointerIndex için IllegalArgumentException olmadan anlayabileceği değeri verilir.

Eğer bu bir anlam ifade etmiyorsa ve daha iyi bir çözüm yolu varsa lütfen bana bildirin, çünkü bunun bununla başa çıkmak için iyi bir yol olmadığından emin olun. Bir başkasının cevabını onaylanmış cevap olarak işaretlemeyi tercih ederim.