Cycle de vie des fragments

Chaque instance Fragment a son propre cycle de vie. Lorsqu'un utilisateur parcourt votre application et interagit avec elle, vos fragments passent par différents états de leur cycle de vie : ajout, suppression, entrée dans l'écran et sortie de l'écran.

Pour gérer le cycle de vie, l'instance Fragment implémente LifecycleOwner, exposant un objet Lifecycle auquel vous pouvez accéder via la méthode getLifecycle().

Chaque état Lifecycle possible est représenté dans l'énumération Lifecycle.State.

En développant l'instance Fragment sur Lifecycle, vous pouvez utiliser les techniques et les classes disponibles pour la gestion des cycles de vie avec des composants tenant compte des cycles de vie. Par exemple, vous pouvez afficher la position de l'appareil à l'écran à l'aide d'un composant tenant compte des cycles de vie. Ce composant peut commencer automatiquement à écouter lorsque le fragment devient actif et s'arrêter lorsque celui-ci passe à un état inactif.

Au lieu d'utiliser un élément LifecycleObserver, la classe Fragment inclut des méthodes de rappel correspondant à chacune des modifications du cycle de vie d'un fragment, parmi lesquelles : onCreate(), onStart(), onResume(), onPause(), onStop() et onDestroy().

La vue d'un fragment comporte un élément Lifecycle distinct géré indépendamment de l'élément Lifecycle du fragment. Les fragments conservent une classe LifecycleOwner pour leur vue, auquel vous pouvez accéder à l'aide des méthodes getViewLifecycleOwner() ou getViewLifecycleOwnerLiveData(). Il est utile d'accéder à la vue de l'élément Lifecycle dans les cas où un composant du cycle de vie ne doit effectuer des tâches qu'à condition que la vue d'un fragment existe, tels que l'observation d'une classe LiveData dont le seul rôle est de s'afficher à l'écran.

Cette rubrique décrit en détail le cycle de vie des éléments Fragment. Elle explique certaines des règles qui déterminent l'état du cycle de vie d'un fragment et montre la relation entre les états Lifecycle et les rappels de cycle de vie des fragments.

Fragments et gestionnaire de fragments

Lorsqu'un fragment est instancié, son premier état est INITIALIZED. Pour qu'un fragment puisse passer aux étapes suivantes de son cycle de vie, il doit être ajouté à un gestionnaire FragmentManager. Le gestionnaire FragmentManager a pour rôle de déterminer l'état dans lequel doit se trouver le fragment, puis d'activer l'état en question pour le fragment.

Au-delà du cycle de vie du fragment, le gestionnaire FragmentManager a aussi pour fonction d'associer les fragments à leur activité hôte et de les dissocier lorsqu'ils ne sont plus utilisés. La classe Fragment comporte deux méthodes de rappel, onAttach() et onDetach(), que vous pouvez remplacer pour effectuer des tâches lorsque l'un de ces événements se produit.

Le rappel onAttach() est activé lorsque le fragment a été ajouté à un gestionnaire FragmentManager et associé à son activité hôte. À ce stade, le fragment est actif et FragmentManager gère son état de cycle de vie. Les méthodes FragmentManager telles que findFragmentById() renvoient alors ce fragment.

La méthode onAttach() est appelée systématiquement avant tout changement d'état du cycle de vie.

Le rappel onDetach() est activé lorsque le fragment a été supprimé d'un gestionnaire FragmentManager et dissocié de son activité hôte. Le fragment n'est plus actif et ne peut plus être récupéré à l'aide de findFragmentById().

La méthode onDetach() est appelée systématiquement après tout changement d'état du cycle de vie.

Notez que ces rappels ne sont pas liés aux méthodes FragmentTransaction attach() et detach(). Pour en savoir plus sur ces méthodes, consultez la page Transactions de fragments.

États et rappels du cycle de vie des fragments

Pour déterminer l'état du cycle de vie d'un fragment, le gestionnaire FragmentManager prend en compte les éléments suivants :

  • L'état maximal d'un fragment est déterminé par son gestionnaire FragmentManager. Un fragment ne peut pas dépasser l'état de son gestionnaire FragmentManager.
  • Dans le cadre d'une opération FragmentTransaction, vous pouvez définir un état de cycle de vie maximal sur un fragment à l'aide de la méthode setMaxLifecycle().
  • L'état du cycle de vie d'un fragment ne peut jamais être supérieur à celui de son parent. Par exemple, un fragment parent ou une activité de même niveau doivent être démarrés avant les fragments enfants correspondants. De même, les fragments enfants doivent être arrêtés avant leur fragment parent ou l'activité de même niveau.
les états du cycle de vie d'un fragment et leur relation, soit les rappels de cycle de vie du fragment, soit le cycle de vie de la vue du fragment
Figure 1. États du cycle de vie (Lifecycle) d'un fragment et leur relation avec les rappels de cycle de vie du fragment et le cycle de vie (Lifecycle) de la vue du fragment.

La figure 1 présente chacun des états Lifecycle d'un fragment et la manière dont ils sont associés aux rappels de cycle de vie du fragment et à la vue Lifecycle de ce fragment.

Le fragment progresse dans son cycle de vie en passant d'un état à un autre. Par exemple, un fragment ajouté en haut de la pile "Retour" remonte de CREATED à STARTED, puis à RESUMED. À l'inverse, lorsqu'un fragment se détache de la pile "Retour", il descend d'un état au suivant, passant de RESUMED à STARTED, puis à CREATED, puis à DESTROYED.

Remontées d'un état à l'autre

Lors d'une remontée des états d'un cycle de vie, un fragment appelle d'abord le rappel de cycle de vie associé à son nouvel état. Une fois ce rappel terminé, l'élément Lifecycle.Event approprié est émis pour les observateurs par le l'élément Lifecycle du fragment, suivi de la vue du fragment Lifecycle, si celle-ci a été instanciée.

Fragment CRÉÉ

Lorsque votre fragment atteint l'état CREATED, il a été ajouté à un gestionnaire FragmentManager et la méthode onAttach() a déjà été appelée.

C'est le moment approprié pour restaurer tout état enregistré associé au fragment lui-même via la propriété SavedStateRegistry de ce fragment. Notez que la vue du fragment n'a pas été créée et que tout état associé à la vue du fragment ne doit être restauré qu'après la création de cette vue.

Cette transition appelle le rappel onCreate(). Le rappel reçoit également un argument Bundle savedInstanceState contenant tout état précédemment enregistré par onSaveInstanceState(). Notez que savedInstanceState a une valeur null la première fois que le fragment est créé, mais qu'il est toujours défini sur une valeur non nulle pour les recréations ultérieures, même si vous n'ignorez pas la méthode onSaveInstanceState(). Pour en savoir plus, consultez la section Enregistrer l'état avec des fragments.

Fragment CRÉÉ et vue INITIALISÉE

La vue Lifecycle du fragment n'est créée que lorsque votre Fragment fournit une instance View valide. Dans la plupart des cas, vous pouvez utiliser les constructeurs de fragments utilisant un identifiant @LayoutId, ce qui gonfle automatiquement la vue au moment souhaité. Vous pouvez également forcer la méthode onCreateView() à gonfler la vue ou à créer la vue de votre fragment de façon programmatique.

Si et seulement si la vue de votre fragment est instanciée avec un élément View non nul, cet élément View est défini sur le fragment et peut être récupéré à l'aide de getView(). La méthode getViewLifecycleOwnerLiveData() est ensuite actualisée avec le nouvel état LifecycleOwner INITIALIZED correspondant à la vue du fragment. Le rappel de cycle de vie onViewCreated() est alors également appelé.

C'est ici que vous devez configurer l'état initial de votre vue, commencer à observer les instances LiveData dont les rappels actualisent la vue du fragment et configurer des adaptateurs sur toutes les instances RecyclerView ou ViewPager2 de la vue de votre fragment.

Fragment et vue CRÉÉS

Une fois la vue du fragment créée, l'état de la vue précédent, le cas échéant, est restauré, et l'élément Lifecycle de la vue passe à l'état CREATED. Le propriétaire du cycle de vie de la vue envoie également l'événement ON_CREATE à ses observateurs. Vous devez alors restaurer tout état supplémentaire associé à la vue du fragment.

Cette transition appelle également le rappel onViewStateRestored().

Fragment et vue DÉMARRÉS

Nous vous recommandons vivement de lier les composants tenant compte des cycles de vie à l'état STARTED d'un fragment, car cet état garantit que la vue du fragment est disponible, le cas échéant, a été créée, et que vous pouvez effectuer une opération FragmentTransaction sur le gestionnaire FragmentManager enfant du fragment. Si la vue du fragment n'est pas nulle, l'état STARTED est appliqué à la vue Lifecycle du fragment immédiatement après l'attribution de l'état STARTED à l'élément Lifecycle du fragment.

Lorsque le fragment acquiert l'état STARTED, le rappel onStart() est appelé.

Fragment et vue REPRIS

Lorsque le fragment est visible, tous les effets Animator et Transition sont terminés, et le fragment peut faire l'objet d'interactions avec l'utilisateur. Le cycle de vie (Lifecycle) du fragment passe à l'état RESUMED, et le rappel onResume() est appelé.

La transition vers l'état RESUMED est le signal approprié pour indiquer que l'utilisateur peut désormais interagir avec votre fragment. Les fragments ne se trouvant pas dans l'état RESUMED ne devraient pas faire ressortir leurs vues manuellement ni tenter de gérer la visibilité du mode de saisie.

Transitions d'état descendantes

Lorsqu'un fragment passe à un état inférieur du cycle de vie, l'événement Lifecycle.Event approprié est envoyé aux observateurs par le cycle de vie (Lifecycle) de la vue du fragment, si celui-ci est instancié, puis par l'élément Lifecycle du fragment. Une fois qu'un événement de cycle de vie a été envoyé, le fragment appelle le rappel de cycle de vie associé.

Fragment et vue DÉMARRÉS

Lorsque l'utilisateur commence à quitter le fragment, mais que celui-ci est toujours visible, les cycles de vie (Lifecycle) du fragment et de sa vue sont restaurés à l'état STARTED et envoient l'événement ON_PAUSE à leurs observateurs. Le fragment appelle ensuite son rappel onPause().

Fragment et vue CRÉÉS

Une fois que le fragment n'est plus visible, l'état CREATED est appliqué aux cycles de vie (Lifecycle) du fragment et de sa vue, qui envoient l'événement ON_STOP à leurs observateurs. Cette transition d'état est déclenchée non seulement par l'activité ou le fragment parent, mais aussi par l'enregistrement de l'état par l'activité parente ou le fragment. Ce comportement garantit que l'événement ON_STOP est appelé avant l'enregistrement de l'état du fragment. L'événement ON_STOP devient ainsi le dernier point où il est possible d'exécuter une opération FragmentTransaction sur le gestionnaire FragmentManager enfant.

Comme le montre la figure 2, l'ordre dans lequel ont lieu le rappel onStop() et l'enregistrement de l'état avec onSaveInstanceState() dépend du niveau d'API. Pour tous les niveaux d'API antérieurs à l'API 28, la méthode onSaveInstanceState() est appelée avant onStop(). Pour les niveaux d'API 28 et supérieurs, l'ordre d'appel est inversé.

différences dans l'ordre des appels pour onStop() et onSaveInstanceState()
Figure 2. Différence dans l'ordre des appels pour onStop() et onSaveInstanceState().

Fragment CRÉÉ et vue DÉTRUITE

Une fois toutes les animations et transitions de sortie terminées et la vue du fragment dissociée de la fenêtre, l'état DESTROYED est attribué au cycle de vie (Lifecycle) de la vue du fragment, qui envoie l'événement ON_DESTROY à ses observateurs. Le fragment appelle ensuite son rappel onDestroyView(). À ce stade, la vue du fragment a atteint la fin de son cycle de vie et getViewLifecycleOwnerLiveData() renvoie une valeur null.

Toutes les références à la vue du fragment doivent alors être supprimées, afin que la mémoire occupée par vue du fragment puisse être récupérée.

Fragment DÉTRUIT

Si le fragment est supprimé ou si le gestionnaire FragmentManager est détruit, l'état DESTROYED est attribué au cycle de vie (Lifecycle) du fragment, qui envoie l'événement ON_DESTROY à ses observateurs. Le fragment appelle ensuite son rappel onDestroy(). Le fragment a alors atteint la fin de son cycle de vie.

Ressources supplémentaires

Pour en savoir plus sur le cycle de vie des fragments, consultez les ressources supplémentaires suivantes.

Guides

Blogs