2013-07-27 7 views
26

Podążyłem za tutorialem Navigation Drawer i wszystko działa jak zaklęcie z wyjątkiem drobnego usterki. Postaram się wyjaśnić to tak bardzo, jak to możliwe, a jeśli nadal nie jest jasne, postaram się przesłać film z problemem.Dlaczego DrawerLayout czasem koliduje z otwarciem?

Problem pojawia się podczas próby otwarcia szuflady i tylko podczas otwierania, a dzieje się to tylko czasami, nie zawsze. To jest, kiedy zaczynam otwierać to to trzaska i zamarza z około 4 milimetrów otwartymi, i zawsze tą samą odległością. Wtedy nie będzie kontynuował otwierania ani zamykania się, jeśli cofnę palec, kiedy puściłem, to się zamknęło.

Uwaga:

  • Próbowałem go na wielu urządzeniach (Nexus 7, Nexus) i urządzeń wirtualnych, jak również, problem nie zniknie.
  • Issue replicated using the example provided by Google. (Youtube Link)
  • Issue presented with my app. (Youtube Link)
  • udało mi się replikować problem raz, ale tylko raz w aplikacji Gmail (co wierzę używa tego samego realizacji), jednak znacznie częściej z mojej aplikacji i aplikacji próbki.
  • Zauważyłem, że błąd występuje w tej samej odległości, z której otwiera się szuflada, gdy klikniesz krawędź ekranu, ponieważ zamarza po początkowym otwarciu i nigdy nie przeciąga.

Wszelkie wskazówki byłyby mile widziane.

+1

Czy możesz dołączyć zrzut ekranu? – PravinCG

+0

Czy to się dzieje, gdy otwierasz menu, przesuwając się od granicy lub naciskając ikonę (zakładając, że zaimplementowano tę funkcję) lub w obu przypadkach? Czy sprawdziłeś logcat pod kątem jakichkolwiek wyjątków? Nigdy nie widziałem czegoś takiego i przetestowałem około 10 urządzeń. Z której wersji biblioteki wsparcia korzystasz? ** p.s. **: Czy ten efekt pojawia się również w przykładowej aplikacji? (patrz http://developer.android.com/training/implementing-navigation/nav-drawer.html) – Trinimon

+0

@Trinimon Zdarza się tylko poprzez przesuwanie. Logcat niczego nie przedstawia. Korzystał z poprzedniej biblioteki pomocy technicznej i właśnie wykonał aktualizację, która została wydana ostatnio i tak się dzieje (wersja 18). Dodałem film do pierwotnego pytania, jeśli chcesz to sprawdzić. – LuckyMe

Odpowiedz

23

Badałem kod DrawerLayout i znalazł kolejny problem: Kiedy dotykać krawędzi ekranu pojawia się niewielki (20 * gęstość px) część drawer (to sprawia, że ​​przenoszenie szuflady łatwiej). Nie pojawia się natychmiast, ale po pewnym czasie (160 ms) czasu. Jest to realizowane przez postDelayed.

Numer drawer może znajdować się w kilku stanach: IDLE, DRAGGING i SETTLING. Jeśli był w stanie DRAGGING, nie może już powrócić do tego stanu z tym samym wskaźnikiem i krawędzią (ponieważ istnieje warunek: mEdgeDragsInProgress[pointerId] & edge) == edge, który nie pozwala przeciągnąć krawędzi, która już była przeciągnięta).

W niektórych przypadkach szuflada została przeniesiona do stanu DRAGGING już po wykonaniu opóźnionego wykonania Runnable. Ta opóźniona czynność powoduje otwarcie drawer dla 20 * gęstości px i zmianę stanu drawer. Tak więc drawer nie może być już przeniesiony (ponieważ nie może powrócić do stanu DRAGGING).

Istnieje kod do anulowania opóźnionej akcji (która otwiera szufladę), ale ten kod w metodzie onInterceptTouchEvent, który jest wywoływany tylko raz (ponieważ zwraca false). Myślę, że ten kod powinien być w metodzie onTouchEvent.

Niestety nie znalazłem żadnego sposobu na anulowanie opóźnionego zdarzenia (ponieważ ma modyfikator private i nie mogę go uzyskać). Więc jedynym sposobem znalazłem: skopiuj kod źródłowy DrawerLayout do mojego projektu i uczynić tę małą zmianę: skopiuj

case MotionEvent.ACTION_MOVE: { 
      // If we cross the touch slop, don't perform the delayed peek for an edge touch. 
      if (mLeftDragger.checkTouchSlop(ViewDragHelper.DIRECTION_ALL)) { 
       mLeftCallback.removeCallbacks(); 
       mRightCallback.removeCallbacks(); 
      } 
      break; 
     } 

od sposobu onInterceptTouchEvent metody onTouchEvent.

+0

Świetne badania, rekwizyty do przeniesienia go na wyższy poziom, po prostu kontynuacja, więc "Opóźnione działanie" 'po wykonaniu zmienia stan na' SETTLING', a następnie 'DRAGGING'? Lub po prostu na' DRAGGING', ale potem to usterki, ponieważ stan był zmieniany z 'DRAGGING' na' DRAGGING' once ag ain? – LuckyMe

+1

Jak rozumiem, stan 'DRAGGING' -' szuflada' podąża za palcem, stan 'SETTLING' -' szuflada' porusza się ze stałą prędkością, np. kiedy uwalniamy go w środku, nadal się przesuwa, aby zamknąć lub otworzyć). 'DelayedRunnable' zmienia stan na' SETTLING' (ponieważ jest to po prostu animacja, 'szuflada' nie podąża za palcem). – esentsov

+3

Innym rozwiązaniem jest użycie Androida: clickable = "true" w głównej zawartości FrameLayout. http://stackoverflow.com/questions/18044277/android-navigation-drawer-bug-using-the-sample –

1

Nie ma błędu w pliku kreacji do gry. Wystarczy dodać ScrollView jako widok rodzica lub root do pliku content.xml (setcontentview) i : context = ". MainActivity"

+1

To pytanie już zawierało odpowiedź, która została przyjęta - po zapoznaniu się z pozostałymi odpowiedziami powinieneś tylko przesłać późną odpowiedź, gdy uważasz, że twoja odpowiedź dodaje wiele wartości (na przykład przy użyciu najnowszych narzędzi/bibliotek widząc, że pytanie ma 3 lata). – ishmaelMakitla

+0

, ale nie sądzę, że rozwiązano problem tutaj –

Powiązane problemy