Puedes proporcionar información adicional o aplicar la misma lógica a los destinos con la clase NavEntryDecorator. Esta clase une cada NavEntry de una pila de actividades con una función de componibilidad. Dicho de otro modo,
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 que admite composición y que se llama para cadaNavEntryde tu pila de actividades. Recibe elNavEntrycomo parámetro. Esto te permite crear objetos de estado que se vinculan a lacontentKeyde la entrada. Puedes usarCompositionLocalProviderpara proporcionar dependencias al contenido de la entrada. También puedes rodear el contenido con una función de componibilidad o activar efectos secundarios. Siempre debes llamar aentry.Content()dentro de este método.onPop: Es una devolución de llamada que se invoca cuando se quita un elementoNavEntryde la pila de actividades y sale de la composición. Recibe elcontentKeyde la entrada quitada. Usa elcontentKeypara 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, úsala 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.
Decora una pila de actividades
Una vez que hayas creado tu NavEntryDecorator, decora las entradas de tu pila de actividades de una de las siguientes dos 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 deNavEntryque puedes usar conNavDisplay. - Proporciona tu decorador directamente a
NavDisplaycon el parámetroentryDecorators.NavDisplayllama arememberDecoratedNavEntriesde forma interna y muestra las entradas decoradas.
Incluye el decorador predeterminado
Navigation 3 incluye un decorador predeterminado llamado
SaveableStateHolderNavEntryDecorator que permite que el estado de un NavEntry se
conserve durante los cambios de configuración y el cierre del proceso. Une el contenido de NavEntry con un SaveableStateProvider, lo que permite que las llamadas de 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 crea con
rememberSaveableStateHolderNavEntryDecorator.
Por ejemplo:
// import androidx.navigation3.runtime.rememberSaveableStateHolderNavEntryDecorator NavDisplay( entryDecorators = listOf( rememberSaveableStateHolderNavEntryDecorator(), remember { CustomNavEntryDecorator() } ), // ... )
Pasa los resultados con ResultEventBusNavEntryDecorator
A partir de Navigation 3 1.2.0, puedes usar ResultEventBusNavEntryDecorator para proporcionar un ResultEventBus a cada NavEntry con la composición local LocalResultEventBus.
De forma predeterminada, rememberResultEventBusNavEntryDecorator crea y recuerda su propia instancia de ResultEventBus de forma interna con rememberResultEventBus. Si necesitas acceder al bus de eventos fuera de la jerarquía de decoradores (como en el scaffolding de la app de nivel superior), puedes elevar el ResultEventBus llamando a rememberResultEventBus y pasándolo a rememberResultEventBusNavEntryDecorator(resultEventBus):
val resultEventBus = rememberResultEventBus() NavDisplay( /* ... */ entryDecorators = listOf( rememberSaveableStateHolderNavEntryDecorator(), rememberResultEventBusNavEntryDecorator(resultEventBus = resultEventBus) ) )
Para obtener más detalles sobre cómo enviar y observar resultados, consulta Cómo devolver resultados.
Cuándo usar un decorador
Usa un decorador para lo siguiente:
- Crea una dependencia para cada
NavEntryen una pila de actividades. Por ejemplo, elViewModelStoreNavEntryDecoratorcrea unViewModelStorepara cadaNavEntry. - Pasar resultados y comunicarse entre destinos Por ejemplo,
ResultEventBusNavEntryDecoratorproporciona unResultEventBusa los destinos de la pila de actividades. - Asignar un objeto a varios
NavEntry. Por ejemplo, para compartir unViewModelentre varias entradas. - Realiza la misma acción para varios
NavEntry. Por ejemplo, para realizar operaciones de registro, depuración o seguimiento de cada entrada. - Une los elementos
NavEntrycon la misma función de componibilidad. - Limpia el estado asociado con los
NavEntry. Por ejemplo, cuando se quita una entrada de la pila de actividades,ViewModelStoreNavEntryDecoratorborra suViewModelStoreasociado.
No uses un decorador para lo siguiente:
- Pasar una dependencia a un solo
NavEntry - Proporcionar dependencias cuyo alcance sea más amplio que la pila de actividades
En ambos casos, pasa la dependencia directamente cuando crees el NavEntry.
Para ver más ejemplos de código, consulta NavEntryDecorator.