我正在使用 Jetpack Compose 和 Hilt 在嵌套导航设置中进行依赖注入。我需要在嵌套屏幕 (NestedHomeScreen) 及其父屏幕 (HomeScreen) 之间共享 ViewModel(具体来说,nested_home ViewModel)。这两个屏幕都是不同导航图的一部分,但我希望 HomeScreen 能够访问 NestedHomeScreen 中使用的相同 ViewModel 实例。
@Composable
fun MainNavGraph(navController: NavHostController) {
NavHost(navController = navController, startDestination = "home") {
composable("home") { HomeScreen(navController) }
composable("profile") { ProfileScreen(navController) }
composable("nested_container") { NestedContainerScreen(navController) }
}
}
@Composable
fun NestedContainerScreen(navController: NavHostController) {
// Create a nested NavController for the subgraph
val nestedNavController = rememberNavController()
// Nested NavHost as the subgraph
NavHost(navController = nestedNavController, startDestination = "nested_home") {
composable("nested_home") {
NestedHomeScreen(nestedNavController)
}
composable("nested_detail/{id}") { backStackEntry ->
val id = backStackEntry.arguments?.getString("id")
NestedDetailScreen(id = id)
}
}
}
val nestedHomeViewModel : HomeViewModel = hiltViewModel()
//need to access it in parent nav host home screen
笔记:
- 不要使用全局范围 viewmodel 与父级 navhost 进行共享
- 不要使用导航子图
NavBackStackEntry
也是一个ViewModelStoreOwner
存储 ViewModel 并使用它们作为String
键返回相同 ViewModel 类的相同 ViewModel 的 。ViewModel 存储ViewModelStore
在如果您将您的范围
ViewModel
与父级一起,NavBackStackEntry
您可以从多个图表或导航访问它。正如你所见,hiltViewModel 采用了
LocalViewModelStoreOwner
来自当前目的地的LocalViewModelStoreOwner.current
还请注意,
getBackStackEntry
如果未找到它会引发异常,因为您可能使用 try-catch,存储常量或使用类型安全导航来确保您访问父 NavBackStackEntry。