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

Вы можете предоставить дополнительную информацию или применить ту же логику к пунктам назначения, используя класс 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 . Например, когда запись удаляется из стека переходов, ViewModelStoreNavEntryDecorator очищает связанный с ней ViewModelStore .

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

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

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

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