2014-10-21 24 views
8

Mam wymagania UX, że użytkownik uruchamia Dialog przez długie naciśnięcie komórki w GridView.Rejestracja UP/CANCEL z okna dialogowego, gdy zdarzenie DOWN zostało wywołane z View's LongPress

  • Choć Dialog wyświetlany jest użytkownik musi być w stanie przenieść ich palca/kciuka po ekranie bez wyzwalania zdarzenie UP/CANCEL gdy opuszczają granice GridView komórce.

  • Gdy użytkownik wreszcie przełamie kontakt z ekranem , to właśnie zamierzam przechwycić. GridView wydaje się rejestrować niektóre fałszywe alarmy dla UP/CANCEL, których nie widzimy przy użyciu innych widoków.

  • Problem jest, że oryginalny widok przechwytuje wszystkich zdarzeń dotykowych, ponieważ DOWN został schwytany przez nią.

  • Okno dialogowe rejestruje/widzi brak dotknięć, aż do zdarzenia UP z oryginalnego widoku.

Próbowałem anulowanie oryginalnego zdarzenia dotykowego i za pomocą dispatchTouch() itp nr radości.

Wszelkie pomysły?

+0

Czy mógłbyś być bardziej konkretny? nie rozumiem, co chcesz robić. – TheRedFox

+0

Widok w działaniu lub fragmencie uruchamia wyświetlanie okna dialogowego, gdy widok jest długi (działa). Użytkownik musi być w stanie oderwać palec od widoku, które wywołało dialog, ale nigdy nie zerwać kontaktu z ekranem. Kiedy i tylko wtedy, gdy użytkownik zerwie kontakt z ekranu, uruchamia inne zdarzenie. Problem: po wyjściu poza granice oryginalnego widoku ACTION_UP i/lub ACTION_CANCEL są wyzwalane i żadne akcenty nie są rejestrowane przez okno dialogowe (ani nic innego), dopóki użytkownik nie zerwie kontaktu z ekranem i nie dokona retuszu. –

+0

Zrobiłem coś podobnego bez widoku siatki. Użytkownik musi nacisnąć długo, pojawi się okno dialogowe, użytkownik może przesuwać palec (naciskając) wszędzie, a gdy użytkownik podniesie palcem okno dialogowe zostanie ukryte. Rozważ nagrywanie filmu i opublikuj go tutaj. Nie zrozumiałem tej części (i żadne dotknięcia nie są rejestrowane przez okno dialogowe (ani nic innego), dopóki użytkownik nie zerwie kontaktu z ekranem i retuszuje.) –

Odpowiedz

2

Użyłem czegoś takiego w jednym z moich projektów.

Przypisz OnTouchListener do każdej komórki gridView i zastąp metodę OnTouch.

@Override 
public boolean onTouch(View v, MotionEvent event) { 

boolean isLongPressed; 

int mSwipeSlop = ViewConfiguration.get(context). 
       getScaledTouchSlop(); 

boolean mSwiping; 

switch (event.getAction()) { 
    case MotionEvent.ACTION_DOWN: 
     handler.postDelayed(mLongPressed, 1000); 
     break; 

    case MotionEvent.ACTION_CANCEL: 
     handler.removeCallbacks(mLongPressed); 
     break; 

    case MotionEvent.ACTION_MOVE: 
     float x = event.getX() + v.getTranslationX(); 
      float deltaX = x - mDownX; 
      float deltaXAbs = Math.abs(deltaX); 
      float y = event.getY() + v.getTranslationY(); 
      float deltaY = Y - mDownY; 
      float deltaYAbs = Math.abs(deltaY); 
      float absDist = Math.sqrt(Math.pow(deltaXAbs, 2) + Math.pow(deltaXAbs, 2)); 
      if (!mSwiping) { 
       if (absDist > mSwipeSlop) { 
        mSwiping = true; 
        handler.removeCallbacks(mLongPressed); 
       } 
      } 
     break; 

    case MotionEvent.ACTION_UP: 
     handler.removeCallbacks(mLongPressed); 
     if (isLongPressed) { 
      // DO ACTION UP 
     } 
     break; 

    default: 
     return false; 
    } 
return true; 
} 

Otwórz okno dialogowe w uruchomionym pliku mLongPressed, które będzie działać tylko wtedy, gdy użytkownik dotknie tego samego miejsca przez sekundę. Możesz zmienić odległość, którą może przesunąć i czas, który musi nacisnąć, aby zarejestrować się jako długie kliknięcie. Jednak polecam używanie getScaledTouchSlop() dla odległości.

final Handler handler = new Handler(); 
Runnable mLongPressed = new Runnable() { 
    public void run() { 
     // OPEN DIALOG 
     isLongPressed = true; 
    } 
}; 

Używając tego kodu w moim projekcie, użytkownik może przesuwać palcem po całym ekranie bez wyzwalania ACTION_UP. Dopiero kiedy podnosi palec, zostaje wyzwolony.