Puoi fornire informazioni aggiuntive o applicare la stessa logica alle destinazioni utilizzando la classe NavEntryDecorator. Questa classe racchiude ogni
NavEntry in un back stack con una funzione componibile. In altre parole, decora i contenuti della voce.
Crea un decoratore personalizzato
Per creare un decoratore, estendi la classe NavEntryDecorator ed esegui l'override
dei seguenti metodi:
decorate: una funzione lambda composable chiamata per ogniNavEntrynello stack indietro. RiceveNavEntrycome parametro. In questo modo, puoi creare oggetti di stato associati all'attributocontentKeydella voce. Puoi utilizzareCompositionLocalProviderper fornire dipendenze ai contenuti della voce. Puoi anche racchiudere i contenuti in una funzione componibile o attivare effetti collaterali. Devi sempre chiamareentry.Content()all'interno di questo metodo.onPop: un callback richiamato quando unNavEntryè stato rimosso dallo stack precedente e ha lasciato la composizione. Riceve ilcontentKeydella voce rimossa. UtilizzacontentKeyper identificare e liberare spazio associato a questa voce.
L'esempio seguente estende la classe NavEntryDecorator per creare un decoratore personalizzato.
// 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 il decoratore deve accedere allo stato, crea una funzione componibile che
crea lo stato e poi lo utilizza per costruire il decoratore. Per un esempio
di implementazione, vedi il codice sorgente di
rememberSaveableStateHolderNavEntryDecorator. In questo modo viene creato lo stato, ovvero un SaveableStateHolder, che viene utilizzato per costruire il decoratore.
Decorare uno stack di ritorno
Dopo aver creato l'NavEntryDecorator, decora le voci dello
stack precedente in uno dei due modi seguenti:
- Utilizza
rememberDecoratedNavEntries. Questa funzione è utile quando hai più back stack, ognuna con il proprio set di decoratori (per maggiori dettagli, consulta questa ricetta di codice). La funzione restituisce un elenco decorato diNavEntryche puoi utilizzare conNavDisplay. - Fornisci il decoratore direttamente a
NavDisplayutilizzando il parametroentryDecorators.NavDisplaycallsrememberDecoratedNavEntriesunder the hood and displays the decorated entries.
Includere il decoratore predefinito
Navigation 3 include un decoratore predefinito denominato
SaveableStateHolderNavEntryDecorator che consente di mantenere lo stato di un NavEntry
durante le modifiche alla configurazione e l'interruzione del processo. Il wrapper
NavEntry include un SaveableStateProvider, che consente
alle chiamate rememberSaveable all'interno dei contenuti NavEntry di funzionare correttamente.
A meno che il tuo decoratore non fornisca un SaveableStateProvider, devi
includere SaveableStateHolderNavEntryDecorator come primo decoratore nell'elenco
dei decoratori forniti. È stato creato utilizzando
rememberSaveableStateHolderNavEntryDecorator.
Ad esempio:
// import androidx.navigation3.runtime.rememberSaveableStateHolderNavEntryDecorator NavDisplay( entryDecorators = listOf( rememberSaveableStateHolderNavEntryDecorator(), remember { CustomNavEntryDecorator() } ), // ... )
Risultati del test utilizzando ResultEventBusNavEntryDecorator
A partire dalla navigazione 3 1.2.0, puoi utilizzare
ResultEventBusNavEntryDecorator per fornire un
ResultEventBus a ogni NavEntry utilizzando la
LocalResultEventBus composizione locale.
Per impostazione predefinita, rememberResultEventBusNavEntryDecorator crea e memorizza internamente la propria istanza ResultEventBus utilizzando rememberResultEventBus. Se devi accedere
al bus degli eventi al di fuori della gerarchia dei decoratori (ad esempio nell'impalcatura
dell'app di primo livello), puoi sollevare ResultEventBus chiamando
rememberResultEventBus e passandolo a
rememberResultEventBusNavEntryDecorator(resultEventBus):
val resultEventBus = rememberResultEventBus() NavDisplay( /* ... */ entryDecorators = listOf( rememberSaveableStateHolderNavEntryDecorator(), rememberResultEventBusNavEntryDecorator(resultEventBus = resultEventBus) ) )
Per ulteriori dettagli sull'invio e l'osservazione dei risultati, vedi Restituisci risultati.
Quando utilizzare un decoratore
Utilizza un decoratore per:
- Crea una dipendenza per ogni
NavEntryin un back stack. Ad esempio,ViewModelStoreNavEntryDecoratorcrea unViewModelStoreper ogniNavEntry. - Passare i risultati e comunicare tra le destinazioni. Ad esempio, l'intent
ResultEventBusNavEntryDecoratorfornisce unResultEventBusalle destinazioni nel back stack. - Definisci l'ambito di un oggetto per più
NavEntry. Ad esempio, per condividere unViewModeltra più voci. - Esegui la stessa azione per più
NavEntry. Ad esempio, per eseguire operazioni di logging, debug o tracciamento per ogni voce. - Esegui il wrapping di
NavEntrycon la stessa funzione componibile. - Libera spazio associato a
NavEntry. Ad esempio, quando una voce viene rimossa dal back stack, l'ViewModelStoreNavEntryDecoratorcancella il relativoViewModelStore.
Non utilizzare un decoratore per:
- Passa una dipendenza a un singolo
NavEntry. - Fornisci dipendenze il cui ambito è più ampio del back stack.
In entrambi i casi, passa la dipendenza direttamente durante la creazione di NavEntry.
Per altri esempi di codice, vedi NavEntryDecorator.