I have a similar problem before and seems like this is the library's expected behavior. I mean, if the user open the app from a deep link which displays the Screen_C and then press back, the app's home screen should be displayed. So maybe you need to revalidate the usability of the app.
However, if even though you want to make a workaround handling the back pressing manually. Using the function below
fun navigatingBack(
navController: NavHostController,
destinationRoute: String
) {
val hasBackstackTheDestinationRoute = navController.backQueue.find {
it.destination.route == destinationRoute
} != null
// if the destination is already in the backstack, simply go back
if (hasBackstackTheDestinationRoute) {
navController.popBackStack()
} else {
// otherwise, navigate to a new destination popping the current destination
navController.navigate(destinationRoute) {
navController.currentBackStackEntry?.destination?.route?.let {
popUpTo(it) {
inclusive = true
}
}
}
}
}
Let's say you declare the screens ScreenA
, ScreenB
and ScreenC
.
composable("__A__") {
ScreenA(navController)
}
composable("__B__") {
ScreenB(navController)
}
composable("__C__") {
ScreenC(navController)
}
You can do the following:
@Composable
fun ScreenA(navController: NavHostController) {
Button(onClick = {
navController.navigate("__B__")
}) {
Text(text = "Screen A - Go to B")
}
}
@Composable
fun ScreenB(navController: NavHostController) {
Button(onClick = {
navController.navigate("__C__")
}) {
Text(text = "Screen B - Go to C")
}
BackHandler {
navigatingBack(navController, "__A__")
}
}
@Composable
fun ScreenC(navController: NavHostController) {
Text(text = "Screen C")
BackHandler {
navigatingBack(navController, "__B__")
}
}
Using the example above, if you navigate directly to the ScreenC
and press back, the ScreenB
will be displayed. The similar happens in ScreenB
, where the ScreenA
is shown when the back button is pressed.