Вы можете добавить дополнительную информацию или применить ту же логику к целевым страницам, используя класс NavEntryDecorator. Этот класс оборачивает каждый элемент NavEntry в обратный стек с помощью composable-функции. Иными словами, она украшает контент записи.
Как создать собственный декоратор
Чтобы создать декоратор, расширьте класс NavEntryDecorator и переопределите следующие методы:
decorate– composable-функция, которая вызывается для каждого элементаNavEntryв обратном стеке. Он получает параметрNavEntry. Это позволяет создавать объекты состояния, связанные сcontentKeyзаписи. Вы можете использоватьCompositionLocalProvider, чтобы указать зависимости для контента записи. Вы также можете обернуть контент в composable-функцию или вызвать побочные эффекты. В этом методе всегда следует вызыватьentry.Content().onPop– обратный вызов, который вызывается, когда объектNavEntryудаляется из стека возврата и композиции. Оно получаетcontentKeyудаленной записи. ИспользуйтеcontentKey, чтобы найти и удалить все данные, связанные с этой записью.
В следующем примере класс NavEntryDecorator расширяется для создания специального декоратора.
// 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") } )
Если декоратору нужен доступ к состоянию, создайте composable-функцию, которая создает это состояние, а затем используйте ее для создания декоратора. Пример реализации можно найти в исходном коде rememberSaveableStateHolderNavEntryDecorator. Это создает состояние – SaveableStateHolder – и использует его для создания декоратора.
Как украсить стопку переходов назад
После того как вы создали NavEntryDecorator, украсьте записи в стеке переходов одним из двух способов:
- Используйте
rememberDecoratedNavEntries. Эта функция полезна, когда у вас несколько стеков возврата, у каждого из которых свой набор декораторов (подробнее в этом рецепте кода). Функция возвращает список элементовNavEntry, которые можно использовать сNavDisplay. - Передайте декоратор непосредственно в
NavDisplay, используя параметрentryDecorators.NavDisplayвызываетrememberDecoratedNavEntriesи показывает измененные записи.
Добавьте декоратор по умолчанию
В Navigation 3 есть декоратор по умолчанию SaveableStateHolderNavEntryDecorator, который позволяет сохранять состояние объекта NavEntry при изменении конфигурации и завершении процесса. Он оборачивает контент NavEntry в SaveableStateProvider, что позволяет правильно выполнять вызовы rememberSaveable внутри контента NavEntry.
Если декоратор не предоставляет SaveableStateProvider, вам следует включить SaveableStateHolderNavEntryDecorator в качестве первого декоратора в список предоставленных декораторов. Он создан с помощью инструмента "rememberSaveableStateHolderNavEntryDecorator".
Пример:
// import androidx.navigation3.runtime.rememberSaveableStateHolderNavEntryDecorator NavDisplay( entryDecorators = listOf( rememberSaveableStateHolderNavEntryDecorator(), remember { CustomNavEntryDecorator() } ), // ... )
Передача результатов с помощью ResultEventBusNavEntryDecorator
Начиная с версии 3 1.2.0 библиотеки Navigation, вы можете использовать ResultEventBusNavEntryDecorator, чтобы передавать ResultEventBus каждому элементу NavEntry с помощью локальной композиции LocalResultEventBus.
По умолчанию rememberResultEventBusNavEntryDecorator создает и запоминает собственный экземпляр ResultEventBus, используя rememberResultEventBus. Если вам нужно получить доступ к шине событий вне иерархии декораторов (например, в каркасе приложения верхнего уровня), вы можете поднять ResultEventBus, вызвав rememberResultEventBus и передав его в rememberResultEventBusNavEntryDecorator(resultEventBus):
val resultEventBus = rememberResultEventBus() NavDisplay( /* ... */ entryDecorators = listOf( rememberSaveableStateHolderNavEntryDecorator(), rememberResultEventBusNavEntryDecorator(resultEventBus = resultEventBus) ) )
Подробнее о том, как отправлять и просматривать результаты…
Когда использовать декоратор
Декоратор позволяет:
- Создайте зависимость для каждого элемента
NavEntryв стеке возврата. Например,ViewModelStoreNavEntryDecoratorсоздаетViewModelStoreдля каждогоNavEntry. - Передавать результаты и обмениваться данными между пунктами назначения. Например,
ResultEventBusNavEntryDecoratorпредоставляетResultEventBusдля пунктов назначения в стеке возврата. - Область действия объекта для нескольких сочетаний клавиш
NavEntry. Например, чтобы разделитьViewModelмежду несколькими записями. - Выполнять одно и то же действие для нескольких
NavEntry. Например, для регистрации, отладки или трассировки каждой записи. - Оберните
NavEntrys в одну и ту же composable-функцию. - Удалите данные, связанные с
NavEntry. Например, когда запись удаляется из стека возврата,ViewModelStoreNavEntryDecoratorочищает связанный с нейViewModelStore.
Не используйте декоратор, чтобы:
- Передавать зависимость в один объект
NavEntry. - Предоставлять зависимости, область действия которых шире, чем у стека возврата.
В обоих случаях передавайте зависимость напрямую при создании NavEntry.
Другие примеры кода можно найти на странице NavEntryDecorator.