Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to handle popping back multiple screens with Jetpack Compose Navigation

I'll try to do some ASCII art to describe the problem:

       <--------------------------------------\
DestinationA --> DestinationC ---------> DestinationE
DestinationB ------/    \-----> DestinationD --/

I hope that's decipherable. C can be reached from destinations A and B. E can be reached from C and D. E returns to either A or B (whichever is in the back stack). Destinations C, D, and E take an argument (id).

What is the best way to implement this? Using nested navigation graphs looks like it might be possible.

The following works, but it feels more like a work-around than how the navigation component is intended to work.

val destination = navController.getBackStackEntry("DestinationC/{id}").destination
navController.popBackStack(destination.id, true)

The usage NavHost is currently:

val navController = rememberNavController()
NavHost(navController = navController, startDestination = "DestinationA") {
    compose("DestinationA") {
        ScreenA(hiltNavGraphViewModel(it))
    }
    compose("DestinationB") {
        ScreenB(hiltNavGraphViewModel(it))
    }
    compose("DestinationC/{id}", arguments = listOf(navArgument("id") { type = NavType.StringType })) {
        val viewModel = hiltNavGraphViewModel(it)
        val id = it.arguments?.getString("id")
        viewModel.setId(id)
        ScreenC(viewModel)
    }
    compose("DestinationD/{id}", arguments = listOf(navArgument("id") { type = NavType.StringType })) {
        val viewModel = hiltNavGraphViewModel(it)
        val id = it.arguments?.getString("id")
        viewModel.setId(id)
        ScreenD(viewModel)
    }
    compose("DestinationE/{id}", arguments = listOf(navArgument("id") { type = NavType.StringType })) {
        val viewModel = hiltNavGraphViewModel(it)
        val id = it.arguments?.getString("id")
        viewModel.setId(id)
        ScreenE(viewModel)
    }
}
like image 950
Sean Avatar asked Nov 06 '22 01:11

Sean


1 Answers

The answer from @rofie-sagara did not work for me. There is a navigation extension that supports routes. I think nested navigation is an unrelated topic. The docs don't really explain why nested navigation is actually useful. My final solutions to move from E back to A or B is:

navigation.popBackStack(route = "DestinationC/{id}", inclusive = true)
like image 133
Sean Avatar answered Nov 14 '22 21:11

Sean