As seções a seguir descrevem estratégias para salvar a backstack e armazenar o estado associado às entradas na backstack.
Salvar a backstack
Garantir que o estado de navegação do app persista em vários eventos do ciclo de vida,
incluindo mudanças de configuração e encerramento de processo, é crucial para uma boa experiência
do usuário. No Navigation 3, você é dono da sua backstack, então não há diretrizes
rígidas sobre como criá-la ou salvá-la. No entanto, o Navigation 3 oferece
um método de conveniência que fornece uma backstack salvável:
rememberNavBackStack
.
Usar rememberNavBackStack
A função combinável rememberNavBackStack
foi projetada para criar uma backstack
que persiste em mudanças de configuração e na interrupção do processo.
Para que rememberNavBackStack
funcione corretamente, cada chave na backstack
precisa obedecer a requisitos específicos:
- Implementar a interface
NavKey
: todas as chaves na backstack precisam implementar a interfaceNavKey
. Isso funciona como uma interface de marcador que sinaliza para a biblioteca que a chave pode ser salva. - Ter a anotação
@Serializable
: além de implementarNavKey
, as classes e os objetos principais precisam ser marcados com a anotação@Serializable
.
O snippet a seguir mostra uma implementação correta de rememberNavBackStack
:
@Serializable data object Home : NavKey @Composable fun NavBackStack() { val backStack = rememberNavBackStack(Home) }
Alternativa: armazenamento em um ViewModel
Outra abordagem para gerenciar a backstack é armazená-la em um ViewModel
.
Para manter a persistência após a interrupção do processo ao usar um ViewModel
ou qualquer outro
armazenamento personalizado, faça o seguinte:
- Verifique se as chaves são serializáveis: assim como no
rememberNavBackStack
, as chaves de navegação precisam ser serializáveis. - Processar a serialização e desserialização manualmente: você é responsável por
salvar manualmente a representação serializada de cada chave no armazenamento persistente e
desserializá-la (por exemplo,
SharedPreferences
, um banco de dados ou um arquivo) quando o app for para segundo plano ou for restaurado.
Como definir o escopo de ViewModel
s para NavEntry
s
ViewModels
são usados para manter o estado relacionado à interface em todas as mudanças de configuração,
como a rotação da tela. Por padrão, ViewModels
são aplicados ao ViewModelStoreOwner
mais próximo, que normalmente é o Activity
ou Fragment
.
No entanto, talvez você queira definir o escopo de uma ViewModel
para uma NavEntry
específica (ou seja, uma
tela ou destino específico) na backstack, em vez de toda a
Activity
. Isso garante que o estado da ViewModel
seja mantido apenas enquanto
essa NavEntry
específica faz parte da backstack e é limpa quando a
NavEntry
é aberta.
A biblioteca de complementos androidx.lifecycle:lifecycle-viewmodel-navigation3
oferece
um NavEntryDecorator
que facilita isso. Esse decorador fornece um
ViewModelStoreOwner
para cada NavEntry
. Quando você cria um ViewModel
dentro do conteúdo de um
NavEntry
(por exemplo, usando viewModel()
no Compose), ele é automaticamente
limitado à chave específica do NavEntry
na backstack. Isso significa que o
ViewModel
é criado quando o NavEntry
é adicionado à backstack e
limpo quando é removido.
Para usar NavEntryDecorator
para definir o escopo de ViewModel
s para NavEntry
s, siga estas
etapas:
- Adicione a dependência
androidx.lifecycle:lifecycle-viewmodel-navigation3
ao arquivoapp/build.gradle.kts
. - Adicione
rememberSavedStateNavEntryDecorator()
à lista deentryDecorators
ao criar umNavDisplay
. - Adicione outros decoradores ao
NavDisplay
.
NavDisplay( entryDecorators = listOf( // Add the default decorators for managing scenes and saving state rememberSceneSetupNavEntryDecorator(), rememberSavedStateNavEntryDecorator(), // Then add the view model store decorator rememberViewModelStoreNavEntryDecorator() ), backStack = backStack, entryProvider = entryProvider { }, )