Cada instância Fragment
tem um
ciclo de vida próprio. Quando um usuário navega e interage com o app, os
fragmentos passam por vários estados no ciclo de vida, à medida que
são adicionados, removidos, entram ou saem da tela.
Para gerenciar o ciclo de vida, Fragment
implementa
LifecycleOwner
, expondo
um objeto Lifecycle
que
pode ser acessado com o
método
getLifecycle()
.
Cada estado Lifecycle
possível é representado na
enumeração Lifecycle.State
.
Ao criar Fragment
em um Lifecycle
, é possível usar as técnicas
e classes disponíveis para
Gerenciar ciclos de vida com componentes que os reconhecem.
Por exemplo, é possível exibir a localização do dispositivo na tela
usando um componente com reconhecimento de ciclo de vida. Esse componente poderá começar a ouvir
automaticamente quando o fragmento se tornar ativo e parar quando o
fragmento passar para um estado inativo.
Como alternativa ao uso de um
LifecycleObserver
, a
classe Fragment
inclui métodos de callback que correspondem a cada uma das
mudanças no ciclo de vida de um fragmento. Eles incluem
onCreate()
,
onStart()
,
onResume()
,
onPause()
,
onStop()
e
onDestroy()
.
A visualização de um fragmento tem um Lifecycle
separado, gerenciado de forma independente
do Lifecycle
do fragmento. Os fragmentos mantêm um
LifecycleOwner
para a visualização, que pode ser acessado usando
getViewLifecycleOwner()
ou
getViewLifecycleOwnerLiveData()
.
Ter acesso ao Lifecycle
da visualização é útil para situações
em que um componente com reconhecimento de ciclo de vida só realiza o trabalho enquanto a
visualização de um fragmento existe, como observar
LiveData
exibido
somente na tela.
Este tópico aborda detalhadamente o ciclo de vida Fragment
, explicando algumas
das regras que determinam o estado do ciclo de vida de um fragmento e mostrando a
relação entre os estados Lifecycle
e os callbacks do ciclo de vida
do fragmento.
Fragmentos e o gerenciador de fragmentos
Quando um fragmento é instanciado, ele começa no estado
INITIALIZED
. Para que um fragmento faça a transição ao longo do restante do ciclo de vida, ele
precisa ser adicionado a um
FragmentManager
. O
FragmentManager
é responsável por determinar em qual estado o fragmento
precisa estar e movê-lo para esse estado.
Além do ciclo de vida do fragmento, FragmentManager
também é responsável por
anexar fragmentos à atividade do host e removê-los quando o
fragmento não estiver mais em uso. A classe Fragment
tem dois métodos de callback,
onAttach()
e onDetach()
, que podem ser substituídos para realizar
o trabalho quando qualquer um desses eventos ocorrer.
O callback onAttach()
é invocado quando o fragmento é adicionado ao
FragmentManager
e anexado à atividade do host. Nesse momento, o
fragmento está ativo e o FragmentManager
está gerenciando o estado do ciclo de
vida. Então, os métodos FragmentManager
, como
findFragmentById()
,
retornam esse fragmento.
onAttach()
é sempre chamado antes de qualquer mudança de estado do ciclo de vida.
O callback onDetach()
é invocado quando o fragmento é removido
de um FragmentManager
e é separado da atividade do host. O
fragmento não está mais ativo e não pode mais ser recuperado usando
findFragmentById()
.
onDetach()
é sempre chamado após qualquer mudança de estado do ciclo de vida.
Esses callbacks não estão relacionados aos
métodos
FragmentTransaction
,
attach()
e
detach()
.
Para ver mais informações sobre esses métodos, consulte
Transações de fragmentos.
Estados de ciclo de vida dos fragmentos e callbacks
Ao determinar o estado do ciclo de vida de um fragmento, FragmentManager
considera
o seguinte:
- O estado máximo de um fragmento é determinado pelo
FragmentManager
. Um fragmento não pode progredir para além do estado doFragmentManager
. - Como parte de uma
FragmentTransaction
, é possível definir um estado de ciclo de vida máximo em um fragmento usandosetMaxLifecycle()
. - O estado do ciclo de vida de um fragmento nunca pode ser maior do que o pai. Por exemplo, um fragmento pai ou uma atividade mãe precisa ser iniciado antes dos fragmentos filhos. Da mesma forma, os fragmentos filhos precisam ser interrompidos antes do fragmento pai ou da atividade mãe.
A Figura 1 mostra cada um dos estados Lifecycle
do fragmento e como eles
estão relacionados aos callbacks do ciclo de vida do fragmento e ao Lifecycle
da visualização do fragmento.
À medida que um fragmento avança pelo ciclo de vida, ele se move para cima e
para baixo entre os estados. Por exemplo, um fragmento adicionado
à parte superior da pilha de retorno avança para cima de CREATED
para
STARTED
e para RESUMED
. Por outro lado, quando um fragmento é retirado
da pilha de retorno, ele se move para baixo entre os estados, passando de
RESUMED
para STARTED
, para CREATED
e, por fim, para DESTROYED
.
Transições de estado para cima
Ao avançar para cima entre os estados de ciclo de vida, um fragmento chama primeiro
o callback do ciclo de vida associado ao novo estado. Quando o callback
é concluído, o
Lifecycle.Event
relevante é
enviado aos observadores pelo Lifecycle
do fragmento, seguido do
Lifecycle
da visualização do fragmento, se instanciado.
Fragmento CREATED
Quando o fragmento atinge o estado CREATED
, ele foi adicionado a
um FragmentManager
e o
método
onAttach()
já foi chamado.
Esse seria o local correto para restaurar qualquer estado salvo
associado ao próprio fragmento com o
SavedStateRegistry
do fragmento.
Nesse momento, a visualização do fragmento ainda não foi criada.
Qualquer estado associado à visualização precisa ser restaurado somente
depois que ela for criada.
Essa transição invoca o
callback
onCreate()
. O callback também recebe um argumento savedInstanceState
Bundle
contendo qualquer estado
salvo anteriormente por
onSaveInstanceState()
.
savedInstanceState
tem valor null
na primeira vez que o
fragmento é criado, mas é sempre não nulo para criações
posteriores, mesmo que você não substitua onSaveInstanceState()
. Consulte
Como salvar o estado com fragmentos para ver mais
detalhes.
Fragmento CREATED e visualização INITIALIZED
O Lifecycle
da visualização do fragmento é criado somente quando o Fragment
fornece uma instância válida de View
. Na
maioria dos casos, é possível usar os
construtores de fragmento
contendo um @LayoutId
, que infla a visualização automaticamente no
momento certo. Você também pode substituir
onCreateView()
para inflar ou criar a visualização do fragmento de forma programática.
Somente se a visualização do fragmento for instanciada com um valor de
View
não nulo, essa View
será definida no fragmento e poderá ser recuperada usando
getView()
. Então, o
getViewLifecycleOwnerLiveData()
será atualizado com o
LifecycleOwner
INITIALIZED
,
correspondente à visualização do fragmento. O
callback do ciclo de vida de onViewCreated()
também é chamado nesse momento.
Esse é o local adequado para configurar o estado inicial da sua visualização,
para começar a observar instâncias de LiveData
com callbacks que atualizam a visualização do fragmento e para configurar
adaptadores em qualquer instância
RecyclerView
ou
ViewPager2
na visualização
do fragmento.
Fragmento e visualização CREATED
Depois que a visualização do fragmento é criada, o estado anterior da visualização, se houver,
é restaurado e o Lifecycle
da visualização é movido para
o estado CREATED
. O proprietário do ciclo de vida da visualização também emite
o evento ON_CREATE
para os observadores. Nesse momento, é necessário restaurar qualquer outro estado associado
à visualização do fragmento.
Essa transição também invoca
o callback
onViewStateRestored()
.
Fragmento e visualização STARTED
É altamente recomendável vincular
componentes com reconhecimento de ciclo de vida ao
estado STARTED
de um fragmento, já que esse estado garante que
a visualização do fragmento esteja disponível, se criada, e que é seguro
executar uma FragmentTransaction
no FragmentManager
filho do fragmento. Se a visualização do fragmento não for nula, o
Lifecycle
dessa visualização será movido para STARTED
imediatamente depois que o
Lifecycle
do fragmento for movido para STARTED
.
Quando o fragmento se torna STARTED
, o
callback onStart()
é invocado.
Fragmento e visualização RESUMED
Quando o fragmento estiver visível, todos
os efeitos de Animator
e
Transition
terão sido
concluídos e o fragmento estará pronto para a interação do usuário. O Lifecycle
do fragmento
é movido para o estado RESUMED
, e o
callback onResume()
é invocado.
A transição para RESUMED
é o sinal adequado para indicar que
o usuário agora pode interagir com o fragmento. Fragmentos que não
são RESUMED
não podem definir o foco manualmente nas visualizações nem tentar
processar a visibilidade do método de entrada.
Transições de estado para baixo
Quando um fragmento se move para baixo para um estado de ciclo de vida inferior, o
Lifecycle.Event
relevante é emitido para os observadores pelo Lifecycle
da visualização do fragmento, se instanciado,
seguido pelo Lifecycle
do fragmento. Depois que o evento de ciclo de vida de um fragmento
é emitido, o fragmento chama o callback do ciclo de vida associado.
Fragmento e visualização STARTED
À medida que o usuário começa a sair do fragmento e este ainda está
visível, os Lifecycle
s do fragmento e da visualização são movidos de volta
para o estado STARTED
e emitem o
evento ON_PAUSE
para os observadores. Em seguida, o fragmento invoca o
callback onPause()
.
Fragmento e visualização CREATED
Quando o fragmento não está mais visível, os Lifecycle
s do fragmento
e a visualização são movidos para o estado CREATED
e emitem o
evento ON_STOP
para os observadores. Essa transição de estado é acionada não somente
quando a atividade ou fragmento pai é interrompido, mas também quando o
estado é salvo pela atividade ou fragmento pai. Esse comportamento garante que
o evento ON_STOP
seja invocado antes que o estado do fragmento seja salvo. Isso
torna o evento ON_STOP
o último ponto em que é seguro realizar uma
FragmentTransaction
no FragmentManager
filho.
Conforme mostrado na figura 2, a ordem do
callback onStop()
e o salvamento do estado com onSaveInstanceState()
são diferentes com base no nível da
API. Para todas as APIs de níveis anteriores ao 28, onSaveInstanceState()
é invocado
antes de onStop()
.
Para as APIs de nível 28 e mais recentes, a ordem de chamada é revertida.
Fragmento CREATED e visualização DESTROYED
Depois que todas as
animações e transições de saída são
concluídas e a visualização do fragmento é removida da janela, o
Lifecycle
da visualização do fragmento é movido para o estado DESTROYED
e emite o
evento ON_DESTROY
para os observadores. Em seguida, o fragmento
invoca o callback
onDestroyView()
. Nesse momento, a visualização do fragmento atinge o fim do ciclo de vida e
getViewLifecycleOwnerLiveData()
retorna um valor null
.
Então, todas as referências à visualização do fragmento precisam ser removidas, permitindo que a visualização do fragmento seja coletada como lixo.
Fragmento DESTROYED
Se o fragmento for removido ou se o FragmentManager
for destruído,
o Lifecycle
do fragmento será movido para o estado DESTROYED
e enviará o evento
ON_DESTROY
aos observadores. Em seguida, o fragmento
invoca o callback
onDestroy()
. Nesse momento, o fragmento atinge o fim do ciclo de vida.
Outros recursos
Para ver mais informações relacionadas ao ciclo de vida do fragmento, consulte os recursos a seguir.
Guias
Blogs
- Fragments: Rebuilding the Internals (link em inglês)