简体   繁体   中英

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)
    }
}

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)

Using nested navigation graphs Make DestinationC and DestinationE on diff navigations.

val navController = rememberNavController()
NavHost(navController = navController, startDestination = "DestinationA") {
    compose("DestinationA") {
        ScreenA(hiltNavGraphViewModel(it))
    }
    compose("DestinationB") {
        ScreenB(hiltNavGraphViewModel(it))
    }
    navigation("DestinationC".plus("/{id}"), "DestinationC".plus("_Route")) {
      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)
    }
    navigation("DestinationE".plus("/{id}"), "DestinationE".plus("_Route")) {
      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)
      }
   }
}

example you want to move from C to E and popUpTo A.

navController.navigate("DestinationE".plus("/${data.id}")) {
                        popUpTo("DestinationA") {
                            inclusive = false
                        }
                    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM