2011-11-29 10 views
6

(Należy pamiętać, że zachowanie opisane w tej kwestii pojawiły się tylko ze względu na coś innego pozornie niepowiązanych robiliśmy. Zobacz the accepted answer.)zmienić sposób SlidingDrawer odpowiada trackball lub kursor

Mamy aktywność Android z GridView i SlidingDrawer wewnątrz RelativeLayout. Sposób, w jaki działanie to reaguje na trackball (lub klawisze kursora), jest raczej dziwny. Fokus zostanie przesunięty pomiędzy pozycjami w oknie GridView, ale gdy tylko kursor przesunie się w kierunku "out" w GridView. (na przykład, gdy u góry, w lewo, gdy znajduje się już na najbardziej wysuniętym w lewo przedmiocie) przesuwana szuflada otwiera się lub zamyka. W szczególności, fokus pozostaje na tym samym przedmiocie w GridView --- nie przesuwa się do przesuwanej szuflady.

Przy pomocy kulki jest to szczególnie okropne, ponieważ kręcenie kulki za Twoim prawdziwym celem spowoduje, że wysuwana szuflada będzie się wielokrotnie otwierać i zamykać.

Ustaliliśmy, że możemy całkowicie wyłączyć trackball przez przesłonięcie onTrackballEvent(). Wolimy, aby trackball i kursor działały normalnie na GridView, ale nie powodują otwierania lub zamykania wysuwanej szuflady. Zasadniczo chcielibyśmy, aby trackball skupił się na różnych zawartości przesuwanej szuflady, gdy jest otwarta.

Jak?

Odpowiedz

0

Jak się okazało, że ten problem spowodowany przez niepowiązanych trochę głupoty. Chcieliśmy klawisz MENU do otwierania i zamykania SlidingDrawer. Zrobiliśmy to, przesyłając: onPrepareOptionsMenu():

public boolean onPrepareOptionsMenu (Menu menu) { 
    slidingDrawer.animateToggle(); 
    return true; 
} 

Działa to dobrze; ale okazuje się, że można go wywołać, gdy menu nie ma być otwarte. W szczególności, jeśli Activity używa setDefaultKeyMode(DEFAULT_KEYS_SHORTCUT), wówczas nieobsłużone zdarzenie kluczowe zakończy dostęp do menu. Obejmuje to ruch trackballa poza krawędzią ekranu.

Im mniej głupi sposób, aby uzyskać pożądane zachowanie jest

public boolean onKeyUp(int keyCode, KeyEvent event) { 
    if(keyCode==KeyEvent.KEYCODE_MENU) { 
     slidingDrawer.animateToggle(); 
    } 
    return super.onKeyUp(keyCode,event); 
} 

Tymczasem możemy uzyskać trackball, aby przejść w SlidingDrawer gdy jest ona otwarta przez utworzenie SlidingDrawer.OnDrawerOpenListener który nazywa

slidingDrawer.getContent().requestFocus(); 

Na koniec warto zadzwonić pod numer

slidingDrawer.getHandle().setFocusable(false); 
3

Można rozważyć utworzenie niestandardowe widoki rozciągające GridView i SlidingDrawer i przy użyciu niestandardowych implementacjach onInterceptTouchEvent i onTouchEvent dla GridView i niestandardową implementację tylko dla onInterceptTouchEvent dla SlidingDrawer. Może nie trzeba zaimplementować zwyczaj SlidingDrawer w zależności od tego, co użytkownik interakcje mogą być wywołane na handle

dla własnych GridView, nadać mu interfejs może zdefiniowane tak:

public interface MyGridViewListener { 
    public boolean shouldPreventScroll(); 
} 

powrotu niestandardowe SlidingDrawer jest otwarty. ta zwracana wartość będzie używana do określenia, czy należy wykonać akcje (dla metod onInterceptTouchEvent i onTouchEvent) na GridView. Tak więc po otwarciu SlidingDrawer czynności wykonane na GridView nie wyzwolą niczego w urządzeniu SlidingDrawer.

aktywny:

MyGridView gridView = (MyGridView) findViewById(R.id.gridView); 
gridView.setMyGridViewListener(new MyGridViewListener() { 
    @Override 
    public boolean shouldPreventScroll() { 
     return slidingDrawer.isOpened(); 
    } 
}); 

MyCustomGridView: shouldIntercept zostanie wywołana, gdy jakieś zdarzenie dotykowy/utworu dzieje się na GridView.

private boolean shouldIntercept() { 
    boolean shouldIntercept = false; 
    if(myGridViewListener != null) { 
     shouldIntercept = myGridViewListener.shouldPreventScroll(); 
    } 
    return shouldIntercept; 
} 
@Override 
public boolean onInterceptTouchEvent(MotionEvent ev) { 
    return shouldIntercept() ? true : super.onInterceptTouchEvent(ev); 
} 
@Override 
public boolean onTouchEvent(MotionEvent ev) { 
    return shouldIntercept() ? true : super.onTouchEvent(ev); 
} 
@Override 
public boolean onTrackballEvent(MotionEvent event) { 
    return shouldIntercept() ? true : super.onTrackballEvent(event); 
} 
public MyGridViewListener getMyGridViewListener() { 
    return myGridViewListener; 
} 
public void setMyGridViewListener(
     MyGridViewListener myGridViewListener) { 
    this.myGridViewListener = myGridViewListener; 
} 

Mam nadzieję punktów w dobrym kierunku, lub przynajmniej pomaga

+0

Przydatne pomysły. Pomógł mi on zastąpić 'open()' w niestandardowym 'SlidingDrawer' i wysłać ślad stosu, który doprowadził do rozwiązania opisanego w zaakceptowanej odpowiedzi. –

1

Podczas zabawy z niestandardowym przesuwne szuflady ustawić układ rączki do jakiegoś dziwnego wartości, coś jak

handle.layout(0, 0,0, 0); 

aby uchwyt znikają ale przeciągając palcem z boku ekranu będzie nadal otwarte szuflady przesuwne, który jest to, czego nie chciał, więc mogę ustawić

handle.layout(10000, 10000, 10000, 10000); 

który przeniósł go drogą poza obszarem widocznym i szuflady nie można już wyciągnąć ręcznie przeciągając z boku ekranu. Po sprawdzeniu kodu źródłowego jego położenia uchwytu, który określa przesuwanie się szuflady, pozbyć się uchwytu i powinno rozwiązać twój problem.

Jeśli potrzebujesz, aby otworzyć/zamknąć szufladę zadzwonić animateOpen()/animateClose()

Powiązane problemy