您可以使用 NavEntryDecorator 类为目的地提供额外信息或应用相同的逻辑。此类使用可组合函数封装了返回栈中的每个 NavEntry。换句话说,它会装饰条目的内容。
创建自定义装饰器
如需创建装饰器,请扩展 NavEntryDecorator 类并替换以下方法:
decorate- 为返回堆栈中的每个NavEntry调用的可组合 lambda。它会接收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搭配使用。 - 使用
entryDecorators参数将装饰器直接提供给NavDisplay。在后台调用NavDisplayrememberDecoratedNavEntries并显示装饰后的条目。
添加默认装饰器
Navigation 3 包含一个名为 SaveableStateHolderNavEntryDecorator 的默认装饰器,该装饰器可让 NavEntry 的状态在配置更改和进程终止后得以保留。它使用 SaveableStateProvider 封装 NavEntry 内容,使 NavEntry 内容中的 rememberSaveable 调用能够正常运行。
除非您的装饰器提供 SaveableStateProvider,否则您应在提供的装饰器列表中包含 SaveableStateHolderNavEntryDecorator 作为第一个装饰器。它是使用 rememberSaveableStateHolderNavEntryDecorator 创建的。
例如:
// import androidx.navigation3.runtime.rememberSaveableStateHolderNavEntryDecorator NavDisplay( entryDecorators = listOf( rememberSaveableStateHolderNavEntryDecorator(), remember { CustomNavEntryDecorator() } ), // ... )
何时使用装饰器
使用装饰器可以:
- 为返回堆栈中的每个
NavEntry创建依赖项。例如,ViewModelStoreNavEntryDecorator会为每个NavEntry创建一个ViewModelStore。 - 将对象限定到多个
NavEntry。例如,在多个条目之间共享ViewModel。 - 对多个
NavEntry执行相同操作。例如,对每个条目执行日志记录、调试或跟踪操作。 - 使用相同的可组合函数封装
NavEntry。 - 清理与
NavEntry关联的状态。例如,当某个条目从返回堆栈中移除时,ViewModelStoreNavEntryDecorator会清除其关联的ViewModelStore。
请勿使用装饰器来执行以下操作:
- 将依赖项传递给单个
NavEntry。 - 提供范围比返回堆栈更广的依赖项。
在这两种情况下,请在创建 NavEntry 时直接传递依赖项。
如需查看更多代码示例,请参阅 NavEntryDecorator。