I am trying to navigate lets say from onboarding to dashboard and beyond and pop the onboarding once user hits dashboard, but still with 'back action' I end up on onboarding again.
Here is the sample code:
@AndroidEntryPoint class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContent { MainUI() } } } @Composable fun MainUI() { val navController = rememberNavController() NavHost( navController = navController, startDestination = "onboarding" ) { composable("onboarding") { Column { Text("I am on onboarding") Button(onClick = { navController.navigate("dashboard") { popUpTo("dashboard") // I want to get rid of onboarding here } }) { Text("go to dashboard") } } } composable("dashboard") { Column { Text("I am on dashboard") Button(onClick = { navController.navigate("detail") }) { Text("go to detail") } } } composable("detail") { Text("I am on detail") } } } This doesn't work either
navController.navigate("dashboard") { popUpTo("dashboard") { inclusive = true // no difference } // .... popUpTo("onboarding") // also nothing // .... popUpTo("onboarding") { inclusive = true // this crashes -> NavGraph cannot be cast to ComposeNavigator$Destination } } For some reason this kind of works, so dashboard is dismissed and from detail I end up on onboarding 🤦
navController.navigate("detail") { popUpTo("dashboard") { inclusive = true } } 4 Answers
I found my solution very easy, if I'm wrong please enlighten me.
navController.popBackStack() 1You can use BackHandler Link:
@Composable fun TestScreen() { BackHandler { // code // example - activity.finish() } } 1As @James Christian Kaguo already said navController.popBackStack() is an option. But you have to be careful when using this method. For some Reason the size of the BackQueue is at least 2 and if popping the backstack lower than that, navigation does not seem to work anymore.
Therefore I wrote following simple extension function:
fun NavController.navigateBack() { if (backQueue.size > 2) { popBackStack() } } 1Well, I've found working solution myself, still not sure if this "boilerplate code" is needed :( But this works as intended, means "page" is dismissed once navigated from it.
NavHost( navController = navController, startDestination = "onboarding" ) { navigation( startDestination = "onboardingUI", route = "onboarding" ) { composable("onboardingUI") { Column { Text("I am on onboarding") Button(onClick = { navController.navigate("dashboard"){ popUpTo("onboarding") } }) { Text("go to dashboard") } } } } navigation(startDestination = "dashboardUI", route = "dashboard") { composable("dashboardUI") { Column { Text("I am on dashboard") Button(onClick = { navController.navigate("detail"){ popUpTo("dashboard") } }) { Text("go to detail") } } } } navigation(startDestination = "detailUI", route = "detail") { composable("detailUI") { Text("I am on detail") } } } } NOTE: route and startDestination AKA name of the composable cannot be same
1