2012-11-01 18 views
8

Mam dwa fragmenty Frag A i Frag B, które są renderowane przy użyciu pager widoku. Jeśli użytkownik przeciągnął od A do B, a następnie naciska przycisk Wstecz (gdy jest w B), wówczas użytkownik powinien przejść do A zamiast wychodzić z widoku pager. Jak możemy to osiągnąć?Jak obsługiwać przycisk Wstecz przy użyciu pagera widoku?

Dodaje transakcji do backstack nie wydaje się pomóc.

Dzięki

Odpowiedz

20

Trzeba zastąpić metodę w ActivityonKeyDown().

@Override 
public boolean onKeyDown(int keyCode, KeyEvent event) { 
    if (keyCode == KeyEvent.KEYCODE_BACK) { 
     myViewPager.setCurrentItem(0, true); 
     return true; 
    } else { 
     return super.onKeyDown(keyCode, event); 
    } 
} 

Spowoduje to przechwycenie zdarzenia "Wstecz" i wysłanie użytkownika do pierwszego elementu w oknie ViewPager.

Istnieje również ViewPager#getCurrentItem(), którego można użyć, aby powrócić tylko wtedy, gdy użytkownik przeciągnął. Implementacja taka jak ta:

@Override 
public boolean onKeyDown(int keyCode, KeyEvent event) { 
    if (keyCode == KeyEvent.KEYCODE_BACK && myViewPager.getCurrentItem() == 1) { 
     myViewPager.setCurrentItem(0, true); 
     return true; 
    } else { 
     return super.onKeyDown(keyCode, event); 
    } 
} 

odeślą użytkownika z powrotem na poprzednią stronę tylko wtedy, gdy użytkownik był na następnej stronie. Inaczej zarejestruje to "z powrotem" normalnie, a użytkownik wyjdzie zgodnie z oczekiwaniami.

Możesz chcieć przypadku, w którym użytkownik powraca do poprzedniej strony (zakładając, że masz więcej niż dwie strony). W takim przypadku chcesz zaimplementować ViewPager.OnPageChangeListener() i zapisać pozycję za każdym razem, gdy zostanie wywołana onPageSelected(int position). Jeśli zaimplementujesz je w stosie, możesz je wysadzić za każdym razem, gdy użytkownik naciśnie przycisk "Wstecz". Gdy stos jest pusty, zamknij aplikację.

EDIT

Jak słusznie stwierdził w komentarzach przez Jade Byfield, nieco łatwiejszy sposób to zrobić byłoby użyć onBackPressed() w Działaniu. Działa to tylko na poziomie API 5+.

@Override 
public void onBackPressed() { 
    if(i_dont_want_to_leave) { 
    myViewPager.setCurrentItem(0, true); 
    } else { 
    super.onBackPressed(); // This will pop the Activity from the stack. 
    } 
} 
+0

Czy mógł również zastąpić onBackPressed? Czy to tylko dla wcześniejszych API? –

+0

Korzystanie z onKeyDown() działa na każdym poziomie API platformy 1+. Ponadto, jeśli nie używam go przez cały czas, onBackPressed nie zapobiegnie wyskakiwaniu tego działania ze stosu. Jeśli zwrócisz 'true' w' onKeyDown() ', to będzie jedyna rzecz, która się wydarzy i zdarzenie przestanie się kaskadować. – DeeV

+0

Czekaj. Po prostu miałem zrzut mózgu. Tak. Może użyć onBackPressed(), jeśli chce kierować na API 5+. Po prostu nie nazywaj 'super.onBackPressed()', chyba że jesteś absolutnie pewny, że chcesz wyjść. – DeeV

0

Myślę, że lepszym podejściem byłoby delegowanie obsługi klucza wstecznego do odpowiednich fragmentów. Użyłem opcji CustomFragment, która obsługuje metodę obsługi klawisza wstecz. Wszystkie Fragmenty będą się rozciągać od tej CustomFragment.

public abstract class BackKeyHandlingFragment extends Fragment { 
    public abstract boolean handleBackKey(); 
} 

Aktywność może delegować przetwarzanie backKey do bieżącego fragmentu. Fragmenty mogą wykonywać wymagane działania w ich odpowiedniej implementacji metody handleBackKey. Metoda może zwrócić wartość "prawda", aby stwierdzić, że aktywność nie przetwarza klucza wstecznego. Aby wykonać domyślne działanie z kluczem wstecznym na poziomie działania, metoda może zwrócić wartość false.

public void onBackPressed() { 
    BackKeyHandlingFragment fragment = (BackKeyHandlingFragment) mSectionsPagerAdapter.getItem(mViewPager.getCurrentItem()); 
    // Fragment should return boolean according to app requirements after processing back key 
    if (!fragment.handleBackKey()) { 
     super.onBackPressed(); 
    } 
} 
Powiązane problemy