Każda instancja Fragment
ma własny cykl życia. Gdy użytkownik porusza się po aplikacji i korzysta z niej, fragmenty kodu przechodzą przez różne stany w trakcie swojego cyklu życia w miarę ich dodawania, usuwania, a także otwierania lub zamykania ekranu.
Aby zarządzać cyklem życia, Fragment
implementuje LifecycleOwner
, udostępniając obiekt Lifecycle
, do którego można uzyskać dostęp za pomocą metody getLifecycle()
.
Każdy możliwy stan Lifecycle
jest reprezentowany w wyliczeniu Lifecycle.State
.
Tworząc Fragment
w oparciu o element Lifecycle
, możesz wykorzystać dostępne techniki i klasy dotyczące postępowania z cyklami życia z użyciem komponentów uwzględniających cykl życia.
Możesz na przykład wyświetlić lokalizację urządzenia na ekranie za pomocą komponentu identyfikującego cykl życia. Ten komponent może automatycznie rozpocząć nasłuchiwanie, gdy fragment stanie się aktywny, i zatrzymać, gdy fragment przejdzie w stan nieaktywny.
Zamiast używać LifecycleObserver
, klasa Fragment
zawiera metody wywołania zwrotnego, które odpowiadają każdej zmianie w cyklu życia fragmentu. Są to między innymi: onCreate()
, onStart()
, onResume()
, onPause()
, onStop()
, onDestroy()
.
Widok danego fragmentu ma osobny element Lifecycle
, którym zarządza się niezależnie od jego elementu Lifecycle
. Fragmenty utrzymują w swoim widoku element LifecycleOwner
, do którego można uzyskać dostęp za pomocą getViewLifecycleOwner()
lub getViewLifecycleOwnerLiveData()
.
Dostęp do Lifecycle
widoku jest przydatny w sytuacjach, gdy komponent zależny od cyklu życia powinien działać tylko wtedy, gdy istnieje widok fragmentu, na przykład obserwować LiveData
, który ma być wyświetlany tylko na ekranie.
W tym temacie szczegółowo omówiono cykl życia elementu Fragment
, wyjaśniamy niektóre reguły, które określają stan cyklu życia fragmentu, i pokazujemy związek między stanami Lifecycle
a wywołaniami zwrotnymi cyklu życia fragmentu.
Fragmenty i menedżer fragmentów
Po utworzeniu fragmentu zaczyna się on od stanu INITIALIZED
. Aby fragment mógł przejść przez resztę cyklu życia, musisz go dodać do FragmentManager
. Element FragmentManager
odpowiada za ustalenie, w jakim stanie powinien się znajdować jego fragment, a następnie za jego przeniesienie do tego stanu.
Poza cyklem życia fragmentu FragmentManager
odpowiada też za dołączanie fragmentów do aktywności hosta i odłączanie ich, gdy fragment nie jest już używany. Klasa Fragment
ma 2 metody wywołań zwrotnych: onAttach()
i onDetach()
, które możesz zastąpić, aby wykonać zadanie, gdy wystąpi jedno z tych zdarzeń.
Wywołanie zwrotne onAttach()
jest wywoływane, gdy fragment został dodany do elementu FragmentManager
i jest dołączony do jego aktywności hosta. W tym momencie fragment jest aktywny, a element FragmentManager
zarządza swoim stanem cyklu życia. W tym momencie metody FragmentManager
, takie jak findFragmentById()
, zwracają ten fragment.
Funkcja onAttach()
jest zawsze wywoływana przed każdą zmianą stanu cyklu życia.
Wywołanie zwrotne onDetach()
jest wywoływane, gdy fragment zostanie usunięty z elementu FragmentManager
i odłączony od jego aktywności hosta. Fragment nie jest już aktywny i nie można go pobrać za pomocą findFragmentById()
.
onDetach()
jest zawsze wywoływana po każdej zmianie stanu cyklu życia.
Pamiętaj, że te wywołania zwrotne nie są powiązane z metodami FragmentTransaction
attach()
i detach()
.
Więcej informacji o tych metodach znajdziesz w artykule Transakcje związane z fragmentem.
Stany cyklu życia fragmentu i wywołania zwrotne
Podczas określania stanu cyklu życia fragmentu, FragmentManager
bierze pod uwagę te kwestie:
- Maksymalny stan fragmentu jest określany przez jego
FragmentManager
. Fragment nie może przejść poza stanFragmentManager
. - W ramach
FragmentTransaction
możesz ustawić maksymalny stan cyklu życia fragmentu za pomocą funkcjisetMaxLifecycle()
. - Stan cyklu życia fragmentu nigdy nie może być wyższy niż jego element nadrzędny. Na przykład fragment nadrzędny lub działanie muszą być rozpoczęte przed jego fragmentami podrzędnymi. Podobnie fragmenty podrzędne należy zatrzymać przed ich fragmentem nadrzędnym lub działaniem.
Rysunek 1 przedstawia każdy stan Lifecycle
fragmentu i jego związek z wywołaniami zwrotnymi w cyklu życia fragmentu i widokiem Lifecycle
danego fragmentu.
Wraz z etapem cyklu życia fragment przesuwa się w górę i w dół w kolejnych stanach. Na przykład fragment dodany na początku stosu wstecznego przesuwa się w górę z CREATED
do STARTED
do RESUMED
. I odwrotnie, gdy fragment zostanie wysunięty z tylnego stosu, przesuwa się w dół przez te stany, w kierunku od RESUMED
do STARTED
do CREATED
, a na koniec do DESTROYED
.
Przejście stanu na wyższy
Przechodząc w górę przez stany cyklu życia fragment, najpierw wywołuje powiązane wywołanie zwrotne cyklu życia, aby uzyskać nowy stan. Po zakończeniu wywołania zwrotnego odpowiedni Lifecycle.Event
jest wysyłany do obserwatorów przez parametr Lifecycle
fragmentu, a po nim widok Lifecycle
fragmentu, jeśli został utworzony.
UTWORZONO Fragment
Gdy fragment osiągnie stan CREATED
, zostanie dodany do FragmentManager
, a metoda onAttach()
została już wywołana.
W tym miejscu warto przywrócić zapisany stan powiązany z samym fragmentem za pomocą metody SavedStateRegistry
danego fragmentu.
Zwróć uwagę, że widok fragmentu nie został jeszcze utworzony, a każdy stan powiązany z widokiem fragmentu powinien zostać przywrócony dopiero po jego utworzeniu.
To przejście wywołuje wywołanie zwrotne onCreate()
. Wywołanie zwrotne odbiera też argument savedInstanceState
Bundle
zawierający dowolny stan zapisany wcześniej przez onSaveInstanceState()
.
Pamiętaj, że przy pierwszym tworzeniu fragmentu savedInstanceState
ma wartość null
, ale przy kolejnych rekreacjach zawsze ma ona wartość niezerową, nawet jeśli nie zastąpisz onSaveInstanceState()
. Więcej informacji znajdziesz w sekcji Zapisywanie stanu z fragmentami.
UTWORZONO Fragment i wyświetl zainicjowany
Widok Lifecycle
fragmentu jest tworzony tylko wtedy, gdy Fragment
zapewnia prawidłową instancję View
. W większości przypadków możesz używać konstruktorów fragmentów, które pobierają @LayoutId
, co automatycznie powiększy widok w odpowiednim momencie. Możesz też zastąpić parametr onCreateView()
, aby automatycznie zwiększać rozmiar lub utworzyć widok fragmentu.
Jeśli widok fragmentu jest utworzony z wartością inną niż zero
View
, tag View
jest ustawiony na fragmencie i można go pobrać za pomocą funkcji getView()
. Następnie w getViewLifecycleOwnerLiveData()
pojawia się nowa wartość INITIALIZED
LifecycleOwner
odpowiadająca widokowi fragmentu. W tej chwili jest też wywoływane wywołanie zwrotne cyklu życia onViewCreated()
.
Tutaj możesz ustawić początkowy stan widoku, rozpocząć obserwację wystąpień LiveData
, których wywołania zwrotne powodują aktualizację widoku fragmentu, oraz skonfigurować adaptery w dowolnych instancjach RecyclerView
lub ViewPager2
w widoku fragmentu.
UTWORZONO Fragment i widok
Po utworzeniu widoku fragmentu przywracany jest poprzedni stan widoku (jeśli występował), a jego element Lifecycle
zostaje przeniesiony do stanu CREATED
. Właściciel cyklu życia widoku wysyła też zdarzenie ON_CREATE
swoim obserwatorom. Tutaj należy przywrócić dowolny dodatkowy stan powiązany z widokiem fragmentu.
To przejście wywołuje też wywołanie zwrotne onViewStateRestored()
.
Fragment i widok: START
Zdecydowanie zalecamy powiązanie komponentów dopasowanych do cyklu życia ze stanem STARTED
fragmentu, ponieważ ten stan gwarantuje, że widok fragmentu jest dostępny, o ile został utworzony, i że można bezpiecznie wykonać FragmentTransaction
na podrzędnym elemencie FragmentManager
danego fragmentu. Jeśli widok fragmentu nie ma wartości null, widok fragmentu (Lifecycle
) jest przenoszony do STARTED
tuż po przeniesieniu jego Lifecycle
do STARTED
.
Gdy fragment zmieni się na STARTED
, wywoływane jest wywołanie zwrotne onStart()
.
Fragment i widok WZNÓW
Gdy fragment jest widoczny, wszystkie efekty Animator
i Transition
zostały zakończone, a fragment jest gotowy do interakcji z użytkownikiem. Lifecycle
fragmentu przechodzi do stanu RESUMED
i jest wywoływane wywołanie zwrotne onResume()
.
Przejście na RESUMED
jest odpowiednim sygnałem, że użytkownik może teraz wchodzić w interakcję z Twoim fragmentem. W przypadku fragmentów, które nie są obiektem RESUMED
, nie należy ręcznie koncentrować się na swoich widokach ani próbować obsługiwać widoczności metody wprowadzania.
Przejścia w dół
Gdy fragment przesuwa się w dół do niższego stanu cyklu życia, odpowiednia wartość Lifecycle.Event
jest wysyłana obserwatorom przez widok Lifecycle
fragmentu (jeśli został utworzony), a po nim następuje Lifecycle
fragmentu. Po wysłaniu zdarzenia cyklu życia fragment ten wywołuje powiązane wywołanie zwrotne cyklu życia.
Fragment i widok: START
Gdy użytkownik zacznie opuszczać fragment, a jego fragment będzie nadal widoczny, parametry Lifecycle
tego fragmentu i jego widoku są przenoszone z powrotem do stanu STARTED
i wysyłają zdarzenie ON_PAUSE
swoim obserwatorom. Następnie fragment wywołuje wywołanie zwrotne onPause()
.
UTWORZONO Fragment i widok
Gdy fragment przestanie być widoczny, parametry Lifecycle
tego fragmentu i jego widoku są przenoszone do stanu CREATED
i wysyłają zdarzenie ON_STOP
swoim obserwatorom. Przejście tego stanu jest aktywowane nie tylko przez zatrzymywane działanie nadrzędne lub fragment, ale także przez zapisanie stanu przez tę aktywność lub fragment. To zachowanie gwarantuje, że zdarzenie ON_STOP
jest wywoływane przed zapisaniem stanu fragmentu. Sprawia to, że zdarzenie ON_STOP
będzie ostatnim punktem, w którym można bezpiecznie wykonać FragmentTransaction
na podrzędnym FragmentManager
.
Jak widać na rysunku 2, kolejność wywołania zwrotnego onStop()
i zapisywanie stanu za pomocą onSaveInstanceState()
różni się zależnie od poziomu interfejsu API. W przypadku wszystkich poziomów interfejsu API starszych niż API 28 obiekt onSaveInstanceState()
jest wywoływany przed onStop()
.
W przypadku interfejsów API na poziomach 28 i wyższych kolejność wywołań jest odwrócona.
UTWORZONO i wyświetl Zniszczony fragment
Po zakończeniu animacji i przejścia wyjścia i odłączeniu widoku fragmentu od okna widok Lifecycle
fragmentu zostaje przeniesiony do stanu DESTROYED
i wysyła zdarzenie ON_DESTROY
swoim obserwatorom. Następnie fragment wywołuje wywołanie zwrotne onDestroyView()
. W tym momencie widok fragmentu osiągnął koniec cyklu życia i getViewLifecycleOwnerLiveData()
zwraca wartość null
.
Na tym etapie należy usunąć wszystkie odniesienia do widoku fragmentu, aby umożliwić zbieranie śmieci.
Zniszczony fragment
Jeśli fragment zostanie usunięty lub FragmentManager
zostanie zniszczony, element Lifecycle
fragmentu zostanie przeniesiony do stanu DESTROYED
i wyśle zdarzenie ON_DESTROY
do swoich obserwatorów. Następnie fragment wywołuje wywołanie zwrotne onDestroy()
. W tym momencie fragment osiągnął koniec cyklu życia.
Dodatkowe materiały
Więcej informacji o cyklu życia fragmentu znajdziesz w tych dodatkowych materiałach.