I had this exact problem.
Sharing my code here.
SHORT ANSWER,
navHostController.popBackStack("routeOfLaunchingScreen", true)
navHostController.navigate("newHomeRoute")
The true
denotes that pop back stack till and including the given route.
Once the back stack is popped as required, we navigate to the new screen.
Hope this solves your issue. :)
LONG ANSWER (copy-paste solution)
MyNavActions.
class MyNavActions(navHostController: NavHostController) {
val navigateTo = { navBackStackEntry: NavBackStackEntry, route: String ->
if (navBackStackEntry.lifecycleIsResumed()) {
navHostController.navigate(route)
}
}
val navigateUp = { navBackStackEntry: NavBackStackEntry ->
if (navBackStackEntry.lifecycleIsResumed()) {
navHostController.navigateUp()
}
}
val popBackStackAndNavigate =
{ navBackStackEntry: NavBackStackEntry, route: String?, popUpTo: String, inclusive: Boolean ->
if (navBackStackEntry.lifecycleIsResumed()) {
navHostController.popBackStack(popUpTo, inclusive)
route?.let {
navHostController.navigate(route)
}
}
}
}
}
/**
* If the lifecycle is not resumed it means this NavBackStackEntry already processed a nav event.
*
* This is used to de-duplicate navigation events.
*/
private fun NavBackStackEntry.lifecycleIsResumed() =
this.lifecycle.currentState == Lifecycle.State.RESUMED
Usage
val myNavActions = remember(navHostController) {
MyNavActions(navHostController)
}
Pop back stack till given route and navigate
chcNavActions.popBackStackAndNavigate(
navBackStackEntry,
routeToPopUpTo,
routeToNavigateTo,
true, // inclusive flag - boolean denoting if the specified route `routeToPopUpTo` should also be popped
)
Back Navigation
chcNavActions.navigateUp(navBackStackEntry)
Simple navigation
chcNavActions.navigateTo(navBackStackEntry, route)