Applicare logica o wrapper alle destinazioni

Puoi fornire informazioni aggiuntive o applicare la stessa logica alle destinazioni utilizzando la classe NavEntryDecorator. Questa classe racchiude ogni NavEntry in uno stack precedente 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 componibile chiamata per ogni NavEntry nello stack precedente. Riceve NavEntry come parametro. In questo modo puoi creare oggetti di stato associati all'contentKey della voce. Puoi utilizzare CompositionLocalProvider per fornire dipendenze ai contenuti della voce. Puoi anche racchiudere i contenuti in una funzione componibile o attivare effetti collaterali. Devi sempre chiamare entry.Content() all'interno di questo metodo.
  • onPop: un callback richiamato quando un NavEntry è stato rimosso dallo stack precedente e ha lasciato la composizione. Riceve il contentKey della voce rimossa. Utilizza contentKey per identificare e ripulire qualsiasi stato 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 tuo decoratore ha bisogno di accedere allo stato, crea una funzione componibile che crei lo stato e poi usalo per costruire il decoratore. Per un esempio di implementazione, consulta il codice sorgente di rememberSaveableStateHolderNavEntryDecorator. Viene creato lo stato, ovvero un SaveableStateHolder, che viene utilizzato per costruire il decoratore.

Decorare uno stack di attività

Dopo aver creato l'NavEntryDecorator, decora le voci dello stack indietro in uno dei due modi seguenti:

  • Utilizza rememberDecoratedNavEntries. Questa funzione è utile quando hai più back stack, ognuno con il proprio insieme di decoratori (per maggiori dettagli, consulta questa ricetta di codice). La funzione restituisce un elenco decorato di NavEntry che puoi utilizzare con NavDisplay.
  • Fornisci il decoratore direttamente a NavDisplay utilizzando il parametro entryDecorators. NavDisplay chiama rememberDecoratedNavEntries in background e mostra le voci decorate.

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 avvolge i contenuti NavEntry con 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() }
    ),
    // ...
)

Quando utilizzare un decoratore

Utilizza un decoratore per:

  • Crea una dipendenza per ogni NavEntry in uno stack precedente. Ad esempio, ViewModelStoreNavEntryDecorator crea un ViewModelStore per ogni NavEntry.
  • Definisci l'ambito di un oggetto per più NavEntry. Ad esempio, per condividere un ViewModel tra 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 NavEntry con la stessa funzione componibile.
  • Pulisci lo stato associato a NavEntry. Ad esempio, quando una voce viene rimossa dallo stack precedente, l'ViewModelStoreNavEntryDecorator cancella il relativo ViewModelStore.

Non utilizzare un decoratore per:

  • Passare una dipendenza a un singolo NavEntry.
  • Fornisci dipendenze il cui ambito è più ampio dello stack precedente.

In entrambi i casi, passa la dipendenza direttamente durante la creazione di NavEntry.

Per altri esempi di codice, vedi NavEntryDecorator.