I have a HomeScreen which has two tabs of horizontal pager which has a similar design:
- Tab 1 has a details screen button which will take you to DetailsScreen Composable.
- Tab 2 again has a similar details screen button which takes you to DetailsScreen composable.
The data selected in details screen can be different hence i want to use different viewmodels for both tabs.
But i also want to use a shared viewmodel for Tab1 Screen and Tab1 DetailsScreen and another sharedviewmodel for Tab2 Screen and Tab2 DetailsScreen.
I checked few other answers and figured out how to use a sharedViewModel but i'm not able to figure out how i can have two seperate sharedViewmodel.
this is my NavHost:
@Composable
fun AppNavHost(
navController: NavHostController
) {
NavHost(navController = navController, startDestination = Screen.HomeScreen.route) {
composable(route = Screen.HomeScreen.route) {
val tab1Viewmodel = it.sharedViewModel<Tab1ScreenViewModel>(navController)
val tab2Viewmodel = it.sharedViewModel<Tab2ScreenViewModel>(navController)
HomeScreenView(
app,
tab1viewmodel,
tab2viewmodel,
{
navController.navigate(
Screen.DetailsScreen.createRoute(
componentId = it.name
)
)
},
{ navController.navigate(Screen.FinalScreen.route) },
)
}
composable(
route = Screen.DetailsScreen.route,
arguments = Screen.DetailsScreen.navArguments
) {
val tab1ViewModel = it.sharedViewModel<Tab1ScreenViewModel>(navController)
val tab2ViewModel = it.sharedViewModel<Tab2ScreenViewModel>(navController)
DetailsScreen(tab1ViewModel, tab2Viewmodel, onBackClick = { navController.navigateUp() })
}
composable(route = Screen.FinalScreen.route) {
FinalScreen { activity.finish() }
}
}
}
@Composable
inline fun <reified T : ViewModel> NavBackStackEntry.sharedViewModel(
navController: NavController,
): T {
val navGraphRoute = destination.parent?.route ?: return hiltViewModel()
val parentEntry = remember(this){
navController.getBackStackEntry(navGraphRoute)
}
return hiltViewModel(parentEntry)
}
Inside homeScreen there are 2 tabs :
@Composable
fun HomeScreenView(
appName: String,
tab1ScreenViewModel: Tab1ScreenViewModel,
tab2ScreenViewmodel: Tab2ScreenViewModel`) {
HorizontalPager() { page ->
selectedTabIndex.value = page
when (page) {
Page.Tab1.ordinal -> Tab1Screen( tab1ScreenViewModel,
goDetailScreenClick)
Page.Tab2.ordinal -> Tab2Screen( tab2ScreenViewmodel, goDetailScreenClick)
}
}
}
@Composable
fun DetailsScreen(
tab1viewModel: Tab1ScreenViewmodel,
tab2viewModel: Tab2screenViewmodel,
onBackClick: () -> Boolean,
) {
}
How will details screen now decide which viewmodel to use ? how to create two different routes for the same details screen when clicked from tab1 and tab2 and have two different viewmodel that is shared between the tab screen and details screen.