Czy istnieje sposób, w jaki możemy wdrożyć onBackPressed()
w Fragmentie Androida podobny do sposobu, w jaki wdrażamy w Aktywności Androida?
Ponieważ cykl życia fragmentu nie ma onBackPressed()
. Czy jest jakaś inna alternatywna metoda przesadzania onBackPressed()
w fragmentach Androida 3.0?
android
android-fragments
onbackpressed
Android_programmer_camera
źródło
źródło
Odpowiedzi:
Rozwiązałem w ten sposób przesłonięcie
onBackPressed
w działaniu. WszystkieFragmentTransaction
sąaddToBackStack
przed zatwierdzeniem:źródło
Moim zdaniem najlepszym rozwiązaniem jest:
ROZWIĄZANIE JAVA
Utwórz prosty interfejs:
I w twojej działalności
Wreszcie w swoim fragmencie:
ROZWIĄZANIE KOTLIN
1 - Utwórz interfejs
2 - Przygotuj swoją aktywność
3 - Zaimplementuj w docelowym fragmencie
źródło
R.id.main_container
? Czy to identyfikator FragmentPager?.?
) i egzekwowanie wartości innych niż null (!!
) może prowadzić do NPE - obsada nie zawsze jest bezpieczna. Wolałbym pisaćif ((fragment as? IOnBackPressed)?.onBackPressed()?.not() == true) { ... }
lub bardziej kotliney(fragment as? IOnBackPressed)?.onBackPressed()?.not()?.let { ... }
.onBackPressed()?.takeIf { !it }?.let{...}
?.not()
po prostu zwraca odwrotność.val fragment = this.supportFragmentManager.findFragmentById(R.id.flContainer) as? NavHostFragment val currentFragment = fragment?.childFragmentManager?.fragments?.get(0) as? IOnBackPressed currentFragment?.onBackPressed()?.takeIf { !it }?.let{ super.onBackPressed() }
To jest dla osób, które używają Kotlin i NavigationControllerWedług @HaMMeRed odpowiedzią jest pseudokod, jak to powinno działać. Powiedzmy, że twoja główna aktywność jest wywoływana i
BaseActivity
zawiera fragmenty potomne (jak w przykładzie lib SlidingMenu). Oto kroki:Najpierw musimy stworzyć interfejs i klasę, która implementuje jego interfejs, aby mieć ogólną metodę
Utwórz interfejs klasy
OnBackPressedListener
Stwórz klasę, która wdraża umiejętności
OnBackPressedListener
Odtąd będziemy pracować nad naszym kodem
BaseActivity
i jego fragmentamiUtwórz prywatnego słuchacza na szczycie swojej klasy
BaseActivity
utwórz metodę ustawiania nasłuchiwacza
BaseActivity
w przesłonięciu
onBackPressed
zaimplementuj coś takiegow swoim fragmencie
onCreateView
należy dodać naszego słuchaczaVoila, teraz kiedy klikniesz z powrotem we fragmencie, powinieneś złapać swoją niestandardową metodę na plecach.
źródło
onBackPressed()
którym fragmencie był wyświetlany po naciśnięciu przycisku Wstecz?((BaseActivity)activity).setOnBackPressedListener(new OnBackpressedListener(){ public void doBack() { //...your stuff here }});
To zadziałało dla mnie: https://stackoverflow.com/a/27145007/3934111
źródło
Jeśli chcesz mieć taką funkcjonalność, musisz zastąpić ją w swojej aktywności, a następnie dodać
YourBackPressed
interfejs do wszystkich swoich fragmentów, które wywołujesz w odpowiednim fragmencie, po każdym naciśnięciu przycisku Wstecz.Edycja: Chciałbym dołączyć moją poprzednią odpowiedź.
Gdybym miał to zrobić dzisiaj, użyłbym transmisji lub ewentualnie transmisji zamówionej, jeśli spodziewałem się, że inne panele zaktualizują się zgodnie z panelem głównym / głównym.
LocalBroadcastManager
w Bibliotece pomocy może ci w tym pomóc, a ty po prostu wysyłasz transmisjęonBackPressed
i subskrybujesz swoje fragmenty, które są dla niej ważne. Wydaje mi się, że Messaging jest implementacją bardziej niezależną od produkcji i skalowałby się lepiej, więc byłoby to teraz moje oficjalne zalecenie dotyczące implementacji. Po prostu użyjIntent
akcji jako filtru wiadomości. wyślij nowo utworzonyACTION_BACK_PRESSED
, wyślij go ze swojej aktywności i nasłuchuj w odpowiednich fragmentach.źródło
LocalBroadcastManager
nie można zrobić zamówionych transmisjiNic z tego nie jest łatwe do wdrożenia ani nie będzie działać w optymalny sposób.
Fragmenty mają wywołanie metody onDetach, które wykona zadanie.
TO BĘDZIE PRACA.
źródło
isRemoving()
zgodnie z opisem w stackoverflow.com/a/27103891/2914140 .Jeśli używasz
androidx.appcompat:appcompat:1.1.0
lub więcej, możesz dodaćOnBackPressedCallback
do swojego fragmentu w następujący sposóbZobacz https://developer.android.com/guide/navigation/navigation-custom-back
źródło
androidx-core-ktx
, możesz użyćrequireActivity().onBackPressedDispatcher.addCallback(viewLifecycleOwner) { /* code to be executed when back is pressed */ }
LifecycleOwner
parametr należy dodać jak w tym przykładzie. Bez niego wszystkie fragmenty rozpoczęte później zadzwonią,handleBackPressed()
jeśli zostanie naciśnięty przycisk Wstecz.Po prostu dodaj
addToBackStack
podczas przechodzenia między fragmentami, jak poniżej:jeśli napiszesz
addToBackStack(null)
, sam sobie z tym poradzi, ale jeśli podasz tag, powinieneś go obsłużyć ręcznie.źródło
ponieważ to pytanie i niektóre odpowiedzi mają ponad pięć lat, podzielę się moim rozwiązaniem. Jest to kontynuacja i modernizacja odpowiedzi @oyenigun
AKTUALIZACJA: Na dole tego artykułu dodałem alternatywną implementację przy użyciu abstrakcyjnego rozszerzenia fragmentu, które w ogóle nie będzie obejmować działania, co byłoby przydatne dla każdego, kto ma bardziej złożoną hierarchię fragmentów obejmującą zagnieżdżone fragmenty, które wymagają innego zachowania wstecznego.
Musiałem to zaimplementować, ponieważ niektóre fragmenty, których używam, mają mniejsze widoki, które chciałbym odrzucić za pomocą przycisku Wstecz, takie jak małe wyskakujące widoki informacji itp., Ale jest to dobre dla każdego, kto musi zastąpić zachowanie przycisk Wstecz wewnątrz fragmentów.
Najpierw zdefiniuj interfejs
Ten interfejs, który nazywam
Backable
(jestem zwolennikiem konwencji nazewnictwa), ma jedną metodę,onBackPressed()
która musi zwrócićboolean
wartość. Musimy wymusić wartość logiczną, ponieważ będziemy musieli wiedzieć, czy naciśnięcie przycisku Wstecz „pochłonęło” zdarzenie Wstecz. Zwrottrue
oznacza, że tak, i nie jest wymagane żadne dalsze działanie, w przeciwnym raziefalse
mówi, że nadal musi nastąpić domyślna akcja wstecz. Ten interfejs powinien być własnym plikiem (najlepiej w osobnym pakiecie o nazwieinterfaces
). Pamiętaj, że dzielenie klas na pakiety to dobra praktyka.Po drugie, znajdź górny fragment
Stworzyłem metodę, która zwraca ostatni
Fragment
obiekt z tylnego stosu. Używam tagów ... jeśli używasz identyfikatorów, wprowadź niezbędne zmiany. Mam tę statyczną metodę w klasie użytkowej, która zajmuje się stanami nawigacji itp., Ale oczywiście umieść ją tam, gdzie najbardziej Ci odpowiada. Dla budowania umieściłem mój w klasie o nazwieNavUtils
.Upewnij się, że liczba tylnych stosów jest większa niż 0, w przeciwnym razie
ArrayOutOfBoundsException
może zostać wyrzucony w czasie wykonywania. Jeśli nie jest większa niż 0, zwróć null. Później sprawdzimy wartość zerową ...Po trzecie, zaimplementuj we fragmencie
Zaimplementuj
Backable
interfejs w dowolnym fragmencie, w którym chcesz zastąpić zachowanie przycisku Wstecz. Dodaj metodę implementacji.W
onBackPressed()
zastąpieniu wprowadź dowolną logikę. Jeśli chcesz, aby przycisk Wstecz nie wyskakiwał z tylnego stosu (zachowanie domyślne), zwróć wartość true , że zdarzenie Wstecz zostało zaabsorbowane. W przeciwnym razie zwróć false.Wreszcie w Twojej działalności ...
Zastąp
onBackPressed()
metodę i dodaj do niej tę logikę:Otrzymujemy bieżący fragment na tylnym stosie, a następnie sprawdzamy zero i sprawdzamy, czy implementuje on nasz
Backable
interfejs. Jeśli tak, określ, czy zdarzenie zostało wchłonięte. Jeśli tak, to konieconBackPressed()
i możemy wrócić. W przeciwnym razie traktuj to jak normalne naciśnięcie wstecz i wywołaj metodę super.Druga opcja nie angażowania działania
Czasami nie chcesz, aby Działanie w ogóle sobie z tym poradziło i musisz obsługiwać to bezpośrednio w tym fragmencie. Ale kto mówi, że nie możesz mieć fragmentów z interfejsem API prasy wstecznej? Po prostu rozszerz swój fragment na nową klasę.
Utwórz klasę abstrakcyjną, która rozszerza Fragment i implementuje
View.OnKeyListner
interfejs ...Jak widać, każdy rozciągający się fragment
BackableFragment
automatycznie przechwytuje kliknięcia wstecz przy użyciuView.OnKeyListener
interfejsu. Wystarczy wywołaćonBackButtonPressed()
metodę abstrakcyjną z zaimplementowanejonKey()
metody, używając standardowej logiki, aby rozpoznać naciśnięcie przycisku Wstecz. Jeśli musisz zarejestrować kliknięcia klawiszy inne niż przycisk Wstecz, pamiętaj, aby wywołaćsuper
metodę podczas zastępowaniaonKey()
fragmentu, w przeciwnym razie zastąpisz zachowanie w abstrakcji.Prosty w użyciu, wystarczy rozszerzyć i wdrożyć:
Ponieważ
onBackButtonPressed()
metoda w superklasie jest abstrakcyjna, po rozszerzeniu należy ją zaimplementowaćonBackButtonPressed()
. Zwraca,void
ponieważ po prostu musi wykonać akcję w klasie fragmentów i nie musi przekazywać absorpcji prasy z powrotem do działania. Upewnij się, że wywołujeszonBackPressed()
metodę Activity , jeśli cokolwiek robisz z przyciskiem Wstecz nie wymaga obsługi, w przeciwnym razie przycisk Wstecz zostanie wyłączony ... i nie chcesz tego!Ostrzeżenia Jak widać, ustawia to kluczowy odbiornik w widoku głównym fragmentu i będziemy musieli go skoncentrować. Jeśli w twoim fragmencie, który rozszerza tę klasę (lub inne wewnętrzne fragmenty lub widoki, które mają to samo), zaangażujesz w tekst fragmenty (lub inne widoki kradnące fokus), musisz poradzić sobie z tym osobno. Jest dobry artykuł o rozszerzaniu EditText, aby stracić skupienie na prasie wstecznej.
Mam nadzieję, że ktoś uzna to za przydatne. Szczęśliwego kodowania.
źródło
super.onBackPressed();
dwa razy?currentFragment
. Jeśli fragment nie jest pusty, a fragment implementujeBackable
interfejs, nie są podejmowane żadne działania. Jeśli fragment nie ma wartości zerowej i NIE jest implementowanyBackable
, wywołujemy metodę super. Jeśli fragment ma wartość null, przechodzi do ostatniego super wywołania.currentFragment
nie jest zerowe i jest instancją Backable i jest odłączone (nacisnęliśmyback
przycisk i zamykamy fragment)super.onBackPressed();
, wywoływane jest pierwsze wystąpienie , a następnie drugie.Rozwiązanie jest proste:
1) Jeśli masz podstawową klasę fragmentów, którą rozszerzają wszystkie fragmenty, dodaj ten kod do jej klasy, w przeciwnym razie utwórz taką klasę fragmentów podstawowych
2) W klasie Activity przesłoń onBackPressed w następujący sposób:
3) W swojej klasie Fragment dodaj żądany kod:
źródło
onBackPressed()
powodują odłączenie Fragmentu od Aktywności.Według odpowiedzi @Sterling Diaz myślę, że ma rację. ALE jakaś sytuacja będzie nie tak. (np. Obróć ekran)
Myślę, że moglibyśmy wykryć, czy
isRemoving()
osiągnąć cele.Możesz to napisać pod adresem
onDetach()
lubonDestroyView()
. To jest praca.źródło
Cóż, zrobiłem to w ten sposób i działa na mnie
Prosty interfejs
FragmentOnBackClickInterface.java
Przykładowa implementacja
MyFragment.java
następnie po prostu przesłonisz onBackPressed w działaniu
źródło
Powinieneś dodać interfejs do swojego projektu jak poniżej;
Następnie powinieneś wdrożyć ten interfejs na swoim fragmencie;
Możesz aktywować to zdarzenie onBackPressed w ramach swoich działań w zdarzeniu onBackPressed, jak poniżej;
źródło
getActivity().onBackPressed();
ponieważ wywoła wyjątek: „java.lang.StackOverflowError: rozmiar stosu 8 MB”.To tylko mały kod, który załatwi sprawę:
Mam nadzieję, że to komuś pomoże :)
źródło
Jeśli używasz EventBus, jest to prawdopodobnie znacznie prostsze rozwiązanie:
aw swojej klasie aktywności możesz zdefiniować:
BackPressedMessage.java jest tylko obiektem POJO
Jest to bardzo czyste i nie ma problemów z interfejsem / implementacją.
źródło
to jest moje rozwiązanie:
źródło
Za pomocą komponentu Nawigacja możesz to zrobić w następujący sposób :
źródło
Co powiesz na użycie onDestroyView ()?
źródło
i = i
lubif (1 < 0) {}
.źródło
we fragmencie dodaj: nie zapomnij zaimplementować interfejsu mainactivity.
źródło
W moim rozwiązaniu (Kotlin);
Używam funkcji onBackAlternative jako parametru w BaseActivity .
BaseActivity
Mam funkcję ustawiania onBackPressAlternative na BaseFragment .
BaseFragment
Wtedy mój onBackPressAlternative jest gotowy do użycia na fragmentach.
Pod fragmenty
źródło
Nie implementuj metody ft.addToBackStack (), aby po naciśnięciu przycisku Wstecz aktywność została zakończona.
źródło
Wystarczy wykonać następujące kroki:
Zawsze podczas dodawania fragmentu
Następnie w głównej czynności zastąp
onBackPressed()
Aby obsłużyć przycisk Wstecz w aplikacji,
Otóż to!
źródło
W cyklu życia aktywności zawsze przycisk Wstecz Androida obsługuje transakcje FragmentManager, gdy korzystaliśmy z FragmentActivity lub AppCompatActivity.
Aby obsłużyć backstacka, nie musimy obsługiwać jego liczby ani niczego tagować, ale powinniśmy się skupić podczas dodawania lub zastępowania fragmentu. Znajdź następujące fragmenty do obsługi przypadków przycisków Wstecz,
Tutaj nie dodam stosu wstecznego do mojego fragmentu głównego, ponieważ jest to strona główna mojej aplikacji. Jeśli dodasz addToBackStack do HomeFragment, aplikacja będzie czekać na usunięcie całej frakcji z aktywnością, a następnie pojawi się pusty ekran, więc utrzymuję następujący warunek,
Teraz możesz zobaczyć poprzednio dodany fragment w usłudze Acitvity, a aplikacja zakończy działanie po osiągnięciu HomeFragment. możesz także spojrzeć na następujące fragmenty.
źródło
Fragment: Stwórz BaseFragment umieszczając metodę:
Czynność:
Twoja aktywność będzie przebiegać po dołączonych i widocznych fragmentach i wywoła onBackPressed () na każdym z nich i przerwie działanie, jeśli jedno z nich zwróci „true” (co oznacza, że zostało to obsłużone, więc nie ma dalszych działań).
źródło
Zgodnie z uwagami do wydania AndroidX ,
androidx.activity 1.0.0-alpha01
został wydany i wprowadzaComponentActivity
nową klasę podstawową istniejącychFragmentActivity
iAppCompatActivity
. A ta wersja przynosi nam nową funkcję:Możesz teraz zarejestrować
OnBackPressedCallback
via,addOnBackPressedCallback
aby otrzymywać połączeniaonBackPressed()
zwrotne bez konieczności zastępowania metody w swojej działalności.źródło
Możesz zarejestrować fragment w działaniu, aby obsłużyć naciśnij wstecz:
stosowanie:
We fragmencie:
W działaniu:
źródło
Zapewnienie niestandardowej nawigacji wstecz poprzez obsługę onBackPressed jest teraz łatwiejsze dzięki wywołaniom zwrotnym wewnątrz fragmentu.
Jeśli chcesz domyślną akcję cofania w oparciu o jakiś warunek, możesz użyć:
źródło
Wewnątrz metody onCreate tego fragmentu dodaj:
źródło
Najlepsze rozwiązanie,
źródło