Aplicar lógica o wrappers a los destinos

Puedes proporcionar información adicional o aplicar la misma lógica a los destinos con la clase NavEntryDecorator. Esta clase une cada NavEntry en una pila de elementos atrás con una función de componibilidad. En otras palabras, decora el contenido de la entrada.

Crea un decorador personalizado

Para crear un decorador, extiende la clase NavEntryDecorator y anula los siguientes métodos:

  • decorate: Es una expresión lambda componible que se llama para cada NavEntry en tu pila de actividades. Recibe el NavEntry como parámetro. Esto te permite crear objetos de estado que se indexan con la clave contentKey de la entrada. Puedes usar CompositionLocalProvider para proporcionar dependencias al contenido de la entrada. También puedes rodear el contenido con una función componible o activar efectos secundarios. Siempre debes llamar a entry.Content() dentro de este método.
  • onPop: Es una devolución de llamada que se invoca cuando se quita un NavEntry de la pila de actividades y sale de la composición. Recibe el contentKey de la entrada quitada. Usa contentKey para identificar y limpiar cualquier estado asociado con esa entrada.

En el siguiente ejemplo, se extiende la clase NavEntryDecorator para crear un 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") }
)

Si tu decorador necesita acceso al estado, crea una función de componibilidad que cree ese estado y, luego, úsalo para construir el decorador. Para ver un ejemplo de implementación, consulta el código fuente de rememberSaveableStateHolderNavEntryDecorator. Esto crea el estado, un SaveableStateHolder, y lo usa para construir el decorador.

Cómo decorar una pila de actividades

Una vez que hayas creado tu NavEntryDecorator, decora las entradas en tu pila de historial de una de las siguientes maneras:

  • Usa rememberDecoratedNavEntries. Esta función es útil cuando tienes varias pilas de actividades, cada una con su propio conjunto de decoradores (consulta esta receta de código para obtener más detalles). La función devuelve una lista decorada de NavEntrys que puedes usar con NavDisplay.
  • Proporciona tu decorador directamente a NavDisplay con el parámetro entryDecorators. NavDisplay llama a rememberDecoratedNavEntries de forma interna y muestra las entradas decoradas.

Incluye el decorador predeterminado

Navigation 3 incluye un decorador predeterminado llamado SaveableStateHolderNavEntryDecorator que permite que se conserve el estado de un NavEntry a través de los cambios de configuración y el cierre del proceso. Encapsula el contenido de NavEntry con un SaveableStateProvider, lo que permite que las llamadas a rememberSaveable dentro del contenido de NavEntry funcionen correctamente.

A menos que tu decorador proporcione un SaveableStateProvider, debes incluir SaveableStateHolderNavEntryDecorator como el primer decorador en tu lista de decoradores proporcionados. Se creó con rememberSaveableStateHolderNavEntryDecorator.

Por ejemplo:

// import androidx.navigation3.runtime.rememberSaveableStateHolderNavEntryDecorator
NavDisplay(
    entryDecorators = listOf(
        rememberSaveableStateHolderNavEntryDecorator(),
        remember { CustomNavEntryDecorator() }
    ),
    // ...
)

Cuándo usar un decorador

Usa un decorador para hacer lo siguiente:

  • Crea una dependencia para cada NavEntry en una pila de historial. Por ejemplo, ViewModelStoreNavEntryDecorator crea un ViewModelStore para cada NavEntry.
  • Asigna un objeto a varios NavEntry. Por ejemplo, para compartir un ViewModel entre varias entradas.
  • Realiza la misma acción para varios NavEntry. Por ejemplo, para realizar operaciones de registro, depuración o seguimiento para cada entrada.
  • Une los elementos NavEntry con la misma función de componibilidad.
  • Se limpia el estado asociado con los objetos NavEntry. Por ejemplo, cuando se quita una entrada de la pila de actividades, ViewModelStoreNavEntryDecorator borra su ViewModelStore asociado.

No uses un decorador para lo siguiente:

  • Pasa una dependencia a un solo NavEntry.
  • Proporciona dependencias cuyo alcance sea más amplio que la pila de actividades.

En ambos casos, pasa la dependencia directamente cuando crees el NavEntry.

Para obtener más ejemplos de código, consulta NavEntryDecorator.