É possível fornecer mais informações ou aplicar a mesma lógica a
destinos usando a classe NavEntryDecorator. Essa classe une cada
NavEntry em uma backstack com uma função combinável. Em outras palavras,
ele decora o conteúdo da entrada.
Criar um decorador personalizado
Para criar um decorador, estenda a classe NavEntryDecorator e substitua
os seguintes métodos:
decorate: uma lambda combinável que é chamada para cadaNavEntryna backstack. Ele recebe oNavEntrycomo parâmetro. Isso permite criar objetos de estado que são vinculados aocontentKeyda entrada. É possível usarCompositionLocalProviderpara fornecer dependências ao conteúdo da entrada. Também é possível cercar o conteúdo com uma função combinável ou acionar efeitos colaterais. Sempre chameentry.Content()dentro desse método.onPop: um callback invocado quando umNavEntryé removido da backstack e sai da composição. Ele recebe ocontentKeyda entrada removida. Use ocontentKeypara identificar e limpar qualquer estado associado a essa entrada.
O exemplo a seguir estende a classe NavEntryDecorator para criar um decorador personalizado.
// import androidx.navigation3.runtime.NavEntryDecorator class CustomNavEntryDecorator<T : Any> : NavEntryDecorator<T>( decorate = { entry -> Log.d("CustomNavEntryDecorator", "entry with ${entry.contentKey} entered composition and was decorated") entry.Content() }, onPop = { contentKey -> Log.d("CustomNavEntryDecorator", "entry with $contentKey was popped") } )
Se o decorador precisar de acesso ao estado, crie uma função combinável que
crie esse estado e use-o para construir o decorador. Para ver um exemplo de implementação, consulte o código-fonte de rememberSaveableStateHolderNavEntryDecorator. Isso cria
o estado, um SaveableStateHolder, e o usa para construir o decorador.
Decorar uma backstack
Depois de criar o NavEntryDecorator, decore as entradas na
backstack de uma destas duas maneiras:
- Use
rememberDecoratedNavEntries. Essa função é útil quando você tem várias backstacks, cada uma com o próprio conjunto de decoradores. Consulte esta receita de código para mais detalhes. A função retorna uma lista decorada deNavEntrys que podem ser usados comNavDisplay. - Forneça o decorador diretamente para
NavDisplayusando o parâmetroentryDecorators. ONavDisplaychamarememberDecoratedNavEntriesem segundo plano e exibe as entradas decoradas.
Incluir o decorador padrão
O Navigation 3 inclui um decorador padrão chamado
SaveableStateHolderNavEntryDecorator que permite que o estado de um NavEntry
seja mantido durante mudanças de configuração e encerramento do processo. Ele envolve
o conteúdo de NavEntry com um SaveableStateProvider, o que permite que as chamadas de
rememberSaveable dentro do conteúdo de NavEntry funcionem corretamente.
A menos que seu decorador forneça um SaveableStateProvider, inclua SaveableStateHolderNavEntryDecorator como o primeiro decorador na lista de decoradores fornecidos. Ele é criado usando
rememberSaveableStateHolderNavEntryDecorator.
Exemplo:
// import androidx.navigation3.runtime.rememberSaveableStateHolderNavEntryDecorator NavDisplay( entryDecorators = listOf( rememberSaveableStateHolderNavEntryDecorator(), remember { CustomNavEntryDecorator() } ), // ... )
Transmitir resultados usando ResultEventBusNavEntryDecorator
A partir do Navigation 3 1.2.0, é possível usar
ResultEventBusNavEntryDecorator para fornecer um
ResultEventBus a cada NavEntry usando o
LocalResultEventBus local de composição.
Por padrão, o rememberResultEventBusNavEntryDecorator cria e armazena na memória a própria instância de ResultEventBus internamente usando rememberResultEventBus. Se você precisar acessar
o barramento de eventos fora da hierarquia do decorador (como no scaffolding do app
de nível superior), eleve o ResultEventBus chamando
rememberResultEventBus e transmitindo-o para
rememberResultEventBusNavEntryDecorator(resultEventBus):
val resultEventBus = rememberResultEventBus() NavDisplay( /* ... */ entryDecorators = listOf( rememberSaveableStateHolderNavEntryDecorator(), rememberResultEventBusNavEntryDecorator(resultEventBus = resultEventBus) ) )
Para mais detalhes sobre como enviar e observar resultados, consulte Retornar resultados.
Quando usar um decorador
Use um decorador para:
- Crie uma dependência para cada
NavEntryem uma backstack. Por exemplo, oViewModelStoreNavEntryDecoratorcria umViewModelStorepara cadaNavEntry. - Transmitir resultados e se comunicar entre destinos. Por exemplo, o
ResultEventBusNavEntryDecoratorfornece umResultEventBuspara destinos na backstack. - Defina o escopo de um objeto para vários
NavEntrys. Por exemplo, para compartilhar umViewModelentre várias entradas. - Realize a mesma ação para vários
NavEntrys. Por exemplo, para realizar operações de geração de registros, depuração ou rastreamento para cada entrada. - Envolva os
NavEntrys com a mesma função combinável. - Limpar o estado associado a
NavEntrys. Por exemplo, quando uma entrada é removida da backstack, oViewModelStoreNavEntryDecoratorlimpa oViewModelStoreassociado.
Não use um decorador para:
- Transmitir uma dependência para um único
NavEntry. - Fornecer dependências com escopo mais amplo do que a backstack.
Nesses dois casos, transmita a dependência diretamente ao criar o NavEntry.
Para mais exemplos de código, consulte NavEntryDecorator.