Reputation: 14787
I am aware there are many similar questions and I have gone through them, still my issue is not solved.
Minified example of my problem,
I have 2 composables ScreenA
and ScreenB
.
Both composables have separate viewmodels.
I am starting at screen A and navigating to screen B. On back button press, I expect the screen B view model to be destroyed. So when I navigate again to screen B, I want its viewmodel to be created again.
ScreenA
@Composable
fun ScreenA(
screenViewModel: ScreenAViewModel = hiltViewModel(),
) {
// Compose code
}
ScreenB
@Composable
fun ScreenB(
screenViewModel: ScreenBViewModel = hiltViewModel(),
) {
// Compose code
}
From the Hilt and Jetpack Navigation Docs, my understanding is using hiltViewModel()
should scope the viewmodel to the particular composable. I am not clear if there is some mistake there.
Added a breakpoint in screen B viewmodel init block. It is reaching init only once when I navigate back and forth.
Referred Questions
How to destroy a ViewModel when user leave a screen
How to share a viewmodel between two or more Jetpack composables inside a Compose NavGraph?
Activity view model in Jetpack compose
Android Compose Navigation and ViewModel lifecycle
Different viewmodel for different composable functions inside same activity
Sample repo with minimum reproducible code - https://github.com/Abhimanyu14/compose-navigation-sample
Upvotes: 4
Views: 4814
Reputation: 14787
The issue was, I was using using CompositionLocalProvider
incorrectly.
This was my initial code.
@Composable
fun MyNavGraph(
activityViewModel: MainActivityViewModel,
viewModelStoreOwner: ViewModelStoreOwner,
) {
val navHostController = rememberNavController()
val myNavActions = remember(navHostController) {
MyNavActions(navHostController)
}
NavHost(
navController = navHostController,
startDestination = Screen.Home.route,
) {
composable(
route = Screen.Home.route,
) { navBackStackEntry ->
CompositionLocalProvider(
LocalViewModelStoreOwner provides viewModelStoreOwner
) {
HomeScreen(
activityViewModel = activityViewModel,
navigateToSettings = {
myNavActions.navigateTo(
navBackStackEntry,
Screen.Settings.route,
)
},
)
}
}
composable(
route = Screen.Settings.route,
) { navBackStackEntry ->
CompositionLocalProvider(
LocalViewModelStoreOwner provides viewModelStoreOwner
) {
SettingsScreen(
activityViewModel = activityViewModel,
)
}
}
}
}
Removing
CompositionLocalProvider(
LocalViewModelStoreOwner provides viewModelStoreOwner
)
fixed the scoping of the viewmodel to composable scope.
Sample repo with initial commit and fixed commit -
https://github.com/Abhimanyu14/compose-navigation-sample
Upvotes: 0