Cada instancia de Fragment
tiene su propio ciclo de vida. Cuando un usuario navega por tu app e interactúa con ella, los fragmentos pasan por varios estados durante su ciclo de vida a medida que se agregan, se quitan e ingresan a la pantalla o salen de ella.
Para administrar el ciclo de vida, Fragment
implementa LifecycleOwner
, lo que expone un objeto Lifecycle
al que puedes acceder a través del método getLifecycle()
.
En la enumeración Lifecycle.State
, se representa cada estado posible de Lifecycle
.
Si compilas Fragment
sobre Lifecycle
, puedes usar las técnicas y clases disponibles para administrar ciclos de vida con componentes optimizados para estos.
Uno de estos componentes te permite mostrar la ubicación del dispositivo en la pantalla. Ese componente podría comenzar a escuchar automáticamente cuando el fragmento se active y detenerse cuando este pase a un estado inactivo.
Como alternativa al uso de un LifecycleObserver
, la clase de Fragment
incluye métodos de devolución de llamada que corresponden a cada uno de los cambios en el ciclo de vida de un fragmento. Se incluyen los siguientes: onCreate()
, onStart()
, onResume()
, onPause()
, onStop()
y onDestroy()
.
La vista de un fragmento tiene un Lifecycle
separado que se administra de forma independiente del Lifecycle
del fragmento. Los fragmentos mantienen un LifecycleOwner
para su vista, al que se puede acceder con getViewLifecycleOwner()
o getViewLifecycleOwnerLiveData()
.
Tener acceso al Lifecycle
de la vista es útil para situaciones en las que un componente optimizado para ciclos de vida solo deba realizar trabajos mientras exista la vista de un fragmento, como observar LiveData
que solo debe mostrarse en la pantalla.
En este tema, se analiza en detalle el ciclo de vida de Fragment
, se explican algunas de las reglas que determinan el estado del ciclo de vida de un fragmento y se muestra la relación entre los estados de Lifecycle
y las devoluciones de llamada de ciclo de vida de los fragmentos.
Los fragmentos y el administrador de fragmentos
Cuando se crea una instancia de un fragmento, este comienza en el estado INITIALIZED
. Para que un fragmento pase por el resto de su ciclo de vida, se lo debe agregar a un FragmentManager
. El FragmentManager
se encarga de determinar el estado que debe tener su fragmento y, luego, de pasarlo a ese estado.
Más allá del ciclo de vida del fragmento, FragmentManager
también se encarga de adjuntar fragmentos a su actividad de host y de separarlos cuando el fragmento ya no esté en uso. La clase Fragment
tiene dos métodos de devolución de llamada, onAttach()
y onDetach()
, que puedes anular para realizar trabajos cuando se produce cualquiera de estos eventos.
Cuando se agrega el fragmento a un FragmentManager
, se invoca la devolución de llamada onAttach()
y se la adjunta a su actividad de host. En este punto, el fragmento está activo y el FragmentManager
administra su estado de ciclo de vida. Asimismo, los métodos de FragmentManager
como findFragmentById()
muestran este fragmento.
Siempre se llama a onAttach()
antes de cualquier cambio de estado de ciclo de vida.
Cuando se quita el fragmento de un FragmentManager
, se invoca la devolución de llamada onDetach()
y se la desconecta de su actividad de host. El fragmento ya no está activo y ya no se puede recuperar con findFragmentById()
.
Siempre se llama a onDetach()
después de cualquier cambio de estado de ciclo de vida.
Ten en cuenta que estas devoluciones de llamada no están relacionadas con los métodos attach()
ni detach()
de FragmentTransaction
.
Para obtener más información sobre estos métodos, consulta Transacciones de fragmentos.
Estados del ciclo de vida de los fragmentos y devoluciones de llamada
A la hora de determinar el estado del ciclo de vida de un fragmento, FragmentManager
tiene en cuenta lo siguiente:
FragmentManager
determina el estado máximo de un fragmento. Un fragmento no puede avanzar más allá del estado de suFragmentManager
.- Como parte de una
FragmentTransaction
, puedes configurar un estado de ciclo de vida máximo para un fragmento consetMaxLifecycle()
. - El estado de ciclo de vida de un fragmento nunca puede ser mayor que su elemento superior. Por ejemplo, una actividad o un fragmento superior deben iniciarse antes que sus fragmentos secundarios. Del mismo modo, los fragmentos secundarios deben detenerse antes de que lo hagan sus fragmentos o actividades superiores.
En la Figura 1, se muestra cada uno de los estados de Lifecycle
del fragmento y la forma en la que se relacionan con las devoluciones de llamada de su ciclo de vida y con el Lifecycle
de su vista.
A medida que un fragmento avanza por su ciclo de vida, se mueve de manera ascendente y descendente por sus estados. Por ejemplo, un fragmento que se agrega a la parte superior de la pila de actividades se mueve de manera ascendente de CREATED
a STARTED
y a RESUMED
. En cambio, cuando un fragmento se quita de la pila de actividades, se mueve de manera descendente por esos estados, de RESUMED
a STARTED
, luego a CREATED
y, por último, a DESTROYED
.
Transiciones de estado ascendentes
Cuando un fragmento se mueve por los estados de su ciclo de vida, primero llama a la devolución de llamada de ciclo de vida asociada a su estado nuevo. Una vez que finaliza la devolución de llamada, se transmite el Lifecycle.Event
correspondiente a los observadores por el Lifecycle
del fragmento, seguido del Lifecycle
de la vista del fragmento, si se creó su instancia.
Fragmento CREADO
Cuando tu fragmento alcanza el estado CREATED
, significa que se lo agregó a un FragmentManager
y ya se llamó al método onAttach()
.
Este sería el lugar adecuado para restablecer el estado guardado asociado con el fragmento a través de su SavedStateRegistry
.
Ten en cuenta que la vista del fragmento aún no se creó, y cualquier estado asociado con la vista del fragmento debe restablecerse solo después de que se haya creado la vista.
Esta transición invoca la devolución de llamada onCreate()
. Esta también recibe un argumento savedInstanceState
Bundle
que contiene cualquier estado guardado con anterioridad por onSaveInstanceState()
.
Ten en cuenta que savedInstanceState
tiene un valor null
la primera vez que se crea el fragmento, pero siempre es no nulo para las recreaciones posteriores, incluso si no anulas onSaveInstanceState()
. Consulta Cómo guardar estados con fragmentos para obtener más detalles.
Fragmento CREADO y vista INICIALIZADA
El Lifecycle
de la vista del fragmento solo se crea cuando tu Fragment
proporciona una instancia válida de View
. En la mayoría de los casos, puedes usar los constructores de fragmentos que toman un @LayoutId
, lo que aumenta automáticamente la vista en el momento apropiado. También puedes anular onCreateView()
para aumentar o crear de manera programática la vista del fragmento.
Siempre y cuando se cree una instancia de la vista del fragmento con una View
no nula, esa View
se establece en el fragmento y se puede recuperar con getView()
. Luego, el getViewLifecycleOwnerLiveData()
se actualiza con el LifecycleOwner
recientemente INITIALIZED
, que corresponde a la vista del fragmento. La devolución de llamada del ciclo de vida de onViewCreated()
también se llama en ese momento.
Este es el lugar adecuado para configurar el estado inicial de la vista a fin de comenzar a observar instancias de LiveData
, cuyas devoluciones de llamada actualizan la vista del fragmento, y también para configurar los adaptadores en cualquier instancia de RecyclerView
o ViewPager2
, en la vista del fragmento.
Fragmento y vista CREADOS
Después de crear la vista del fragmento, se restablece el estado anterior de la vista, si existe, y el Lifecycle
de la vista pasa al estado CREATED
. El propietario del ciclo de vida de la vista también emite el evento ON_CREATE
a sus observadores. Aquí debes restablecer cualquier estado adicional asociado con la vista del fragmento.
Esta transición también invoca la devolución de llamada onViewStateRestored()
.
Fragmento y vista COMENZADOS
Se recomienda que vincules los componentes optimizados para ciclos de vida al estado STARTED
de un fragmento, ya que este estado garantiza que la vista del fragmento, si se creó alguna, esté disponible y que sea seguro realizar una FragmentTransaction
en el FragmentManager
secundario del fragmento. Si la vista del fragmento no es nula, el Lifecycle
de la vista del fragmento pasa a STARTED
inmediatamente después de que el Lifecycle
del fragmento pase a STARTED
.
Cuando el fragmento pasa a STARTED
, se invoca la devolución de llamada onStart()
.
Fragmento y vista REANUDADOS
Cuando el fragmento sea visible, habrán finalizado todos los efectos de Animator
y Transition
, y el fragmento estará listo para la interacción del usuario. El Lifecycle
del fragmento pasa al estado RESUMED
y se invoca la devolución de llamada onResume()
.
La transición a RESUMED
es la señal correspondiente que indica que el usuario ahora puede interactuar con el fragmento. Los fragmentos que no tengan el estado RESUMED
no deben establecer manualmente el foco en sus vistas ni intentar controlar la visibilidad del método de entrada.
Transiciones de estado descendentes
Cuando un fragmento se mueve hacia un estado inferior del ciclo de vida, el Lifecycle
de la vista del fragmento, si se creó una instancia de esta, emite el Lifecycle.Event
correspondiente a los observadores, seguido del Lifecycle
del fragmento. Después de que se emite el evento del ciclo de vida de un fragmento, este último llama a la devolución de llamada de ciclo de vida asociada.
Fragmento y vista COMENZADOS
Cuando el usuario comienza a dejar el fragmento y mientras este aún está visible, los Lifecycle
del fragmento y de su vista vuelven a pasar al estado STARTED
y a emitir el evento ON_PAUSE
a sus observadores. Luego, el fragmento invoca su devolución de llamada onPause()
.
Fragmento y vista CREADOS
Una vez que el fragmento ya no esté visible, los Lifecycle
del fragmento y de su vista pasarán al estado CREATED
y emitirán el evento ON_STOP
a sus observadores. Esta transición de estado se activa no solo cuando se detiene la actividad o el fragmento superiores, sino también cuando alguno de ellos guarda un estado. Este comportamiento garantiza que el evento ON_STOP
se invoque antes de que se guarde el estado del fragmento. Esto hace que el evento ON_STOP
sea el último punto en el que es seguro realizar una FragmentTransaction
en el FragmentManager
secundario.
Como se muestra en la Figura 2, el orden de la devolución de llamada onStop()
y el guardado del estado con onSaveInstanceState()
difieren según el nivel de API. En todos los niveles de API anteriores a la API 28, onSaveInstanceState()
se invoca antes de onStop()
.
En el caso de los niveles de API 28 y posteriores, el orden de llamada está invertido.
Fragmento CREADO y vista DESTRUIDA
Una vez que se completaron todas las animaciones y transiciones de salida y que la vista del fragmento se separó de la ventana, el Lifecycle
de la vista del fragmento pasa al estado DESTROYED
y emite el evento ON_DESTROY
a sus observadores. Luego, el fragmento invoca su devolución de llamada onDestroyView()
. En este punto, la vista del fragmento alcanzó el final de su ciclo de vida y getViewLifecycleOwnerLiveData()
muestra un valor null
.
Asimismo, se deben quitar todas las referencias a la vista del fragmento, lo que permitirá la recolección de elementos no utilizados.
Fragmento DESTRUIDO
Si se quita el fragmento, o si se destruye el FragmentManager
, el Lifecycle
del fragmento pasa al estado DESTROYED
y envía el evento ON_DESTROY
a sus observadores. Luego, el fragmento invoca su devolución de llamada onDestroy()
. En este punto, el fragmento alcanzó el final de su ciclo de vida.
Recursos adicionales
Para obtener más información relacionada con el ciclo de vida de los fragmentos, consulta los siguientes recursos adicionales.