Применить логику или оболочки к пунктам назначения

Вы можете добавить дополнительную информацию или применить ту же логику к пунктам назначения, используя класс NavEntryDecorator . Этот класс оборачивает каждый NavEntry в стек возврата с компонуемой функцией. Другими словами, он декорирует содержимое записи.

Создайте собственный декоратор

Для создания декоратора расширьте класс NavEntryDecorator и переопределите следующие методы:

  • decorate — это компонуемая лямбда-функция, которая вызывается для каждого NavEntry в вашем стеке возврата. Она принимает NavEntry в качестве параметра. Это позволяет создавать объекты состояния, которые привязаны к contentKey записи. Вы можете использовать CompositionLocalProvider для предоставления зависимостей от содержимого записи. Вы также можете окружить содержимое компонуемой функцией или запускать побочные эффекты. Внутри этого метода всегда следует вызывать 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") }
)

Если вашему декоратору необходим доступ к состоянию, создайте компонуемую функцию, которая создает это состояние, а затем используйте её для построения декоратора. Пример реализации можно найти в исходном коде 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() }
    ),
    // ...
)

Когда следует обратиться к декоратору?

Используйте декоратор для:

  • Создайте зависимость для каждого NavEntry в стеке возврата. Например, ViewModelStoreNavEntryDecorator создает ViewModelStore для каждого NavEntry .
  • Присвойте объекту область действия нескольких элементов NavEntry . Например, чтобы использовать одну и ту же ViewModel для нескольких элементов NavEntry.
  • Выполните одно и то же действие для нескольких элементов NavEntry . Например, для выполнения операций логирования, отладки или трассировки для каждого элемента.
  • Оберните элементы NavEntry в ту же самую составную функцию.
  • Очистка состояния, связанного с элементами NavEntry . Например, когда элемент удаляется из стека "Назад", ViewModelStoreNavEntryDecorator очищает связанный с ним ViewModelStore .

Не используйте дизайнера интерьеров для:

  • Передайте зависимость отдельному элементу NavEntry .
  • Укажите зависимости, область действия которых шире, чем стек вызовов.

В обоих этих случаях передавайте зависимость напрямую при создании элемента NavEntry .

Дополнительные примеры кода см. в разделе NavEntryDecorator .