这正是
导航图作用域的视图模型所用的目的。
它包括两个步骤:
查找与要为其设置ViewModel的图形关联的NavBackStackEntry
将其传递给viewModel()
。
对于第一步,您有两个选项。如果您知道导航图的路线(通常应该知道),则可以直接使用
getBackStackEntry
:
val navigationGraphEntry = remember {
navController.getBackStackEntry("graph_route")
}
val navigationGraphScopedViewModel = viewModel(navigationGraphEntry)
然而,如果你需要更加通用的方法,你可以通过目标页面本身的信息 - 其parent
来获取返回栈条目:
fun NavBackStackEntry.rememberParentEntry(): NavBackStackEntry {
val parentId = navBackStackEntry.destination.parent!!.id
return remember {
navController.getBackStackEntry(parentId)
}
}
这使您可以编写类似以下内容的代码:
val parentEntry = it.rememberParentEntry()
val navigationGraphScopedViewModel = viewModel(parentEntry)
当您使用嵌套导航时,parent
目标将等于图形的中间层之一,而对于简单导航图,它将等于根图。
NavHost(navController, startDestination = startRoute) {
...
navigation(startDestination = nestedStartRoute, route = nestedRoute) {
composable(route) {
val parentViewModel: YourViewModel = viewModel(it.rememberParentEntry())
}
composable(route) {
val parentViewModel: YourViewModel = viewModel(it.rememberParentEntry())
}
}
navigation(startDestination = nestedStartRoute, route = secondNestedRoute) {
composable(route) {
val parentViewModel: YourViewModel = viewModel(it.rememberParentEntry())
}
}
composable(route) {
val parentViewModel: YourViewModel = viewModel(it.rememberParentEntry())
}
...
}
请注意,您不仅限于直接父级:每个父级导航图都可以用于提供更大的范围。