I have tried all possible way looks like not getting a solution to this.
I am using an all compose app with compose screens and using compose navigation to navigate between this screen, I have a scenario where I am navigating further in this manner
Screen A > Screen B1 >..> Screen BN > Screen C
Now After I have done with the function on Screen C, I want to pop back to Screen A but this time with an optional argument for eg: Success
I have done this to navigate to A:
val route = "ScreenA?arg={arg}"
// navigating like this
navController.navigate("ScreenA")
// handling
composable(route, arguments = listOf(navArgument("arg") { nullable = true })){
ScreenA()
}
Now for popping back to ScreenA from where ever I am I have done this:
navController.popBackStack(
route = route,
inclusive = false
)
I want to send argument now while popping back. I have tried adding route as
ScreenA?arg=success
Which Doesn't work as inside popBackStack function, it checks the hashcode of the route
popBackStack(createRoute(route).hashCode(), inclusive, saveState)
in this case my navigation fails
I have tried setting argument to back stack entry also but as it can be N Screen in between it wont work. Need to understand where I am doing wrong or if theres a way to do it?
Try setting value to previousBackStackEntry like
navController.previousBackStackEntry?.savedStateHandle?.set(
"resultStatus",
true
)
from the second screen and in the first screen which is ScreenA add
val noResultData =
backStackEntry.savedStateHandle.getLiveData<Boolean>("resultStatus")
.observeAsState(false)
inside the composable(route){ backStackEntry -> } .This might fix your issue.
Once it is used you can remove it like this
backStackEntry.savedStateHandle.remove<Boolean>("resultStatus")
I do this here https://github.com/google/horologist/blob/5884bfd051e5692dae874003ded80c4c39375c93/media-ui/src/main/java/com/google/android/horologist/media/ui/navigation/MediaNavController.kt#L64
It's effectively
public fun NavController.navigateToXWithArgument() {
navigate("player?page=0") {
popUpTo("player?page={page}") {
inclusive = true
saveState = false
}
}
}
I think it's important that the route in popUpTo does not have any real values, so it's exactly what you passed in when you defined the route.
In my case to read it, I use a LaunchedEffect to react when it gets set and remove it, but you may want something different.
val pageParam = backStack.arguments?.getInt(page, -1) ?: -1
backStack.arguments?.remove(page)
LaunchedEffect(pageParam) {
if (pageParam != null) {
// do something
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With