2012-06-23 6 views
7

Mam do niego dołączony przycisk i OnTouchListener. Jak mogę się dowiedzieć, czy ruch (gdy użytkownik naciśnie przycisk) nastąpił wewnątrz czy na zewnątrz? Zarówno event.getAction(), jak i event.getActionMasked() zwracają tylko 0, 1 lub 2, czyli odpowiednio ActionDown, ActionUp, ActionMove. Istnieje stała wartość parametru MotionEvent.ACTION_OUTSIDE, która wynosi 4, ale jakoś nie jest dostępna, nawet jeśli przeciągnę przycisk poza przycisk - nadal otrzymuję 2 z obu metod. Jaki jest problem?Android MotionEvent: sprawdź, czy ruch wystąpił poza widokiem.

UPD: Znalazłem fajne rozwiązanie - po prostu sprawdź stan skupienia na widoku po ACTION_UP. Jeśli nie jest skoncentrowany, oznacza to, że ruch nastąpił poza widokiem.

Odpowiedz

7

Ta flaga ma zastosowanie tylko do systemu Windows, a nie widoków. Otrzymasz ACTION_MOVE po zdjęciu palca z widoku, a wydarzenie pozostanie w widoku, z którego pochodzi. Spójrz na kod źródłowy dla SeekBar, jeśli potrzebujesz wyjaśnienia: nawet jeśli zdejmiesz palec z paska, kciuk nadal będzie ciągnąć!

Aby to zrobić na poziomie okna, użyj FLAG_WATCH_OUTSIDE_TOUCH, to działa dobrze.

3

Jeśli OnTouchListener jest ustawiony na Button, zdarzenia ruchu będą odbierane tylko z poziomu Button. MotionEvent.ACTION_OUTSIDE zostanie wywołany tylko wtedy, gdy zdarzenie ruchu po raz pierwszy wykracza poza granice View, i powinieneś traktować go tak, jakby był ACTION_UP.

5

case MotionEvent.ACTION_CANCEL pracował dla mnie.

+0

Dlaczego to nie jest oznaczony jako odpowiedź, nigdy się nie dowiem. Dzięki. :) –

+0

Ta odpowiedź naprawdę rozwiązuje mój problem. Dziękuję Ci bardzo. –

4

MotionEvent.ACTION_OUTSIDE nie działa dla widoku.

Jednym rozwiązaniem jest uzyskanie pozycji dotykowej X i Y i sprawdzenie, czy znajduje się ona wewnątrz granic widoku. Można to zrobić tak:

@Override 
public boolean onTouchEvent(MotionEvent e) { 
    if (e.getX()<0 || e.getY()<0 || e.getX()>getMeasuredWidth() || e.getY()>getMeasuredHeight()) 
     Log.i(TAG, "TOUCH OUTSIDE"); 
    else 
     Log.i(TAG, "TOUCH INSIDE"); 

    return true; 
} 
0
public static boolean touchWithinBounds(MotionEvent event, View view) { 
    if (event == null || view == null || view.getWidth() == 0 || view.getHeight() == 0) 
     return false; 

    int[] viewLocation = new int[2]; 
    view.getLocationOnScreen(viewLocation); 
    int viewMaxX = viewLocation[0] + view.getWidth() - 1; 
    int viewMaxY = viewLocation[1] + view.getHeight() - 1; 
    return (event.getRawX() <= viewMaxX && event.getRawX() >= viewLocation[0] 
     && event.getRawY() <= viewMaxY && event.getRawY() >= viewLocation[1]); 
} 

rozwiązanie dla gdy jesteś spedycja dotykowy zdarzenia z innego widoku

Powiązane problemy