2011-12-20 10 views
20

Mam kilka widoków dotyczących działania, które użytkownik chce szybko dotknąć i przechwytuję te dotknięcia, używając TouchListener i obsługi MotionEvent.ACTION_DOWN. Jednakże, jeśli użytkownik używa dwóch rąk, bardzo prawdopodobne jest, że następny widok zostanie "dotknięty" zanim użytkownik wyciągnie poprzedni palec w górę. W tym scenariuszu, MotionEvent.ACTION_MOVE jest uruchamiany dla pierwszego widoku zamiast pożądanego MotionEvent.ACTION_DOWN dla drugiego widoku.Wyłączanie lub zapobieganie multitouch w działaniu

Czy istnieje sposób obejścia tego problemu lub zapobieżenia temu? Próbowałem wysłać nowe wydarzenie z MotionEvent.ACTION_UP, a także usunąć detektor zdarzeń, ale nic nie działa.

+0

http: // stackoverflow.com/questions/8570982/disable-or-prevent-multitouch-in-activity/36281321 # 36281321 –

Odpowiedz

4

Najlepszym sposobem, aby to obejść W tym scenariuszu należy użyć metody ViewGroup i zaimplementować metodę onInterceptTouchEvent, aby ręcznie kierować zdarzeniami dotykowymi zgodnie z oczekiwaniami.

ta została pierwotnie tutaj odpowiedzi: Android multitouch! hack anyone?

Kod wdrożenie tego rozwiązania (znajdujący się w sekcji komentarzy w odpowiedzi na powyższe pytanie) znajduje się tutaj: http://pastebin.com/hiE1aTCw

2

Mam rozwiązać to za pomocą metody niestandardowej - czego nie chcesz zrobić, jeśli ktoś znajdzie lepszy sposób chciałbym usłyszeć o nim podziękowań:

public static void setViewGroupEnebled(ViewGroup view, boolean enabled) 
{ 
    int childern = view.getChildCount(); 

    for (int i = 0; i< childern ; i++) 
    { 
     View child = view.getChildAt(i); 
     if (child instanceof ViewGroup) 
     { 
      setViewGroupEnebled((ViewGroup) child,enabled); 
     } 
     child.setEnabled(enabled); 
    } 
    view.setEnabled(enabled); 
} 
7

zrobiłem to tak:

@Override 
public boolean onTouchEvent(MotionEvent event) { 
    // TODO Auto-generated method stub 

    if(event.getPointerCount() > 1) { 
     System.out.println("Multitouch detected!"); 
     return true; 
    } 
    else 
     return super.onTouchEvent(event); 
} 

Myślę, że możesz zastąpić TouchEvent dla dowolnego widoku.

56

Najprostszym sposobem znalazłem zmusić jednym dotknięciem w poprzek całej aplikacji jest ustawienie go przy użyciu motywu:

<style name="MyTheme" parent="@android:style/Theme.Holo.Light"> 
    <item name="android:windowEnableSplitTouch">false</item> 
    <item name="android:splitMotionEvents">false</item> 
</style> 

manifeście:

<application 
     android:label="@string/app_name" 
     android:theme="@style/MyTheme" > 
+0

Dla informacji "android: splitMotionEvents" wymaga poziomu API 11 i powyżej – gjman2

+0

To nie działa na Androidzie 5.0 i powyżej – ThanosFisherman

+3

Praca dla mnie w systemie Android 5.0.1. –

0
int currentapiVersion = android.os.Build.VERSION.SDK_INT; 

      if (currentapiVersion >= android.os.Build.VERSION_CODES.HONEYCOMB) { 

       horizentalLinearGridItem.setMotionEventSplittingEnabled(false); 

      } 

Tutaj horizentalLinearGridItem jest widok parentLayout gdzie wstawiamy widoki podrzędne. W moim kodzie jest to LinearLayout. W tym LinearLayout dodano widoki podrzędne. Ale gdy kliknąłem dwa widoki podrzędne jednocześnie, obaj otrzymywali zdarzenia. Aby zablokować, użyłem powyższego kodu.

8

jeśli ktoś wciąż szuka najlepszego rozwiązania, umieścić w xml następujący kod:

android:splitMotionEvents = false 
+0

Najprostszym rozwiązaniem roboczym –

0

Dostałem go do pracy dla mnie po prostu dodając trochę kodu w OnTouchEvent metodzie

boolean action_down_required = false; 

@Override 
public boolean onTouchEvent(MotionEvent event) { 

    int action = event.getAction(); 

    if(event.getPointerCount() > 1){ 
     action_down_required = true; 
     return true; 
    } 

    if(action_down_required){ 
     action = MotionEvent.ACTION_DOWN; 
    } 

    switch (action) { 
     case MotionEvent.ACTION_DOWN: 

      // your code goes here... 

      action_down_required = false; 
      break; 

     // Other events... 
1

Zastąpienie dispatchTouchEvent i przechwyć wszystkie dotknięcia tam, dla wszystkich multi touchów licznik jest większy niż jeden.

if(ev.getPointerCount() > 1) 
    { 
    Log.d("Multitouch detected!"); 
    ev.setAction(MotionEvent.ACTION_CANCEL); 
    } 

Anuluje to dotknięcie i usuwa naciśnięty stan przycisków bez podejmowania dalszych działań.

Powiązane problemy