admin管理员组文章数量:1025227
I'm working with Jetpack Compose and Hilt for dependency injection in a nested navigation setup. I need to share a ViewModel (specifically, nested_home ViewModel) between a nested screen (NestedHomeScreen) and its parent screen (HomeScreen). Both screens are part of different navigation graphs, but I want the HomeScreen to be able to access the same ViewModel instance used in NestedHomeScreen.
@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
Note:
- Do not use global scope viewmodel to parent navhost to share
- Do not use subgraph using navigation
I'm working with Jetpack Compose and Hilt for dependency injection in a nested navigation setup. I need to share a ViewModel (specifically, nested_home ViewModel) between a nested screen (NestedHomeScreen) and its parent screen (HomeScreen). Both screens are part of different navigation graphs, but I want the HomeScreen to be able to access the same ViewModel instance used in NestedHomeScreen.
@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
Note:
- Do not use global scope viewmodel to parent navhost to share
- Do not use subgraph using navigation
1 Answer
Reset to default 2NavBackStackEntry
is also a ViewModelStoreOwner
that stores ViewModels and return same ViewModels for same ViewModel classes by using them as String
keys. ViewModels are stored in ViewModelStore
with
private val map = mutableMapOf<String, ViewModel>()
If you scope your ViewModel
with a parent NavBackStackEntry
you can access it from multiple graphs or navigations.
val parentBackStackEntry: NavBackStackEntry = navController.getBackStackEntry("home")
val nestedHomeViewModel : HomeViewModel = hiltViewModel(parentBackStackEntry)
As you can see hiltViewModel takes a LocalViewModelStoreOwner
which is from current destination via LocalViewModelStoreOwner.current
@Composable
inline fun <reified VM : ViewModel> hiltViewModel(
viewModelStoreOwner: ViewModelStoreOwner = checkNotNull(LocalViewModelStoreOwner.current) {
"No ViewModelStoreOwner was provided via LocalViewModelStoreOwner"
},
key: String? = null
): VM {
val factory = createHiltViewModelFactory(viewModelStoreOwner)
return viewModel(viewModelStoreOwner, key, factory = factory)
}
Also be advised that getBackStackEntry
is not found it throws exception because of that you might use try-catch, store a constant or use type-safe navigation to make sure that you access parent NavBackStackEntry.
I'm working with Jetpack Compose and Hilt for dependency injection in a nested navigation setup. I need to share a ViewModel (specifically, nested_home ViewModel) between a nested screen (NestedHomeScreen) and its parent screen (HomeScreen). Both screens are part of different navigation graphs, but I want the HomeScreen to be able to access the same ViewModel instance used in NestedHomeScreen.
@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
Note:
- Do not use global scope viewmodel to parent navhost to share
- Do not use subgraph using navigation
I'm working with Jetpack Compose and Hilt for dependency injection in a nested navigation setup. I need to share a ViewModel (specifically, nested_home ViewModel) between a nested screen (NestedHomeScreen) and its parent screen (HomeScreen). Both screens are part of different navigation graphs, but I want the HomeScreen to be able to access the same ViewModel instance used in NestedHomeScreen.
@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
Note:
- Do not use global scope viewmodel to parent navhost to share
- Do not use subgraph using navigation
1 Answer
Reset to default 2NavBackStackEntry
is also a ViewModelStoreOwner
that stores ViewModels and return same ViewModels for same ViewModel classes by using them as String
keys. ViewModels are stored in ViewModelStore
with
private val map = mutableMapOf<String, ViewModel>()
If you scope your ViewModel
with a parent NavBackStackEntry
you can access it from multiple graphs or navigations.
val parentBackStackEntry: NavBackStackEntry = navController.getBackStackEntry("home")
val nestedHomeViewModel : HomeViewModel = hiltViewModel(parentBackStackEntry)
As you can see hiltViewModel takes a LocalViewModelStoreOwner
which is from current destination via LocalViewModelStoreOwner.current
@Composable
inline fun <reified VM : ViewModel> hiltViewModel(
viewModelStoreOwner: ViewModelStoreOwner = checkNotNull(LocalViewModelStoreOwner.current) {
"No ViewModelStoreOwner was provided via LocalViewModelStoreOwner"
},
key: String? = null
): VM {
val factory = createHiltViewModelFactory(viewModelStoreOwner)
return viewModel(viewModelStoreOwner, key, factory = factory)
}
Also be advised that getBackStackEntry
is not found it throws exception because of that you might use try-catch, store a constant or use type-safe navigation to make sure that you access parent NavBackStackEntry.
本文标签: kotlinHow to share nested nav graph screen viewmodel to parent nav graph screenStack Overflow
版权声明:本文标题:kotlin - How to share nested nav graph screen viewmodel to parent nav graph screen - Stack Overflow 内容由热心网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://it.en369.cn/questions/1745616005a2159296.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论