Methew
Methew

Reputation: 51

Compose navigate to screen that already in backstack

I want to have navigation that looks like this:

-I have three screens: "Login", "Registration", and "Account recovery";

-from each screen, I can navigate to any other;

-when I navigate from the "Login" screen to "Registration" and then return to the "Login" (clicking the button "Go to login"), I want to have the same screen as at the beginning, not a new one.

Now, each time, when I go back to "Login", I get a new screen :(

My NavHost:

    val navController = rememberNavController()

    NavHost(navController = navController, startDestination = Screens.Login.route) {
        composable(route = Screens.Recovery.route) {
            RecoveryScreen(navController = navController)
        }
        composable(route = Screens.Login.route) {
            LoginScreen(navController = navController)
        }
        composable(route = Screens.Registration.route) {
            RegistrationScreen(navController = navController)
        }
    }

Guide me which way to dig?

Upvotes: 4

Views: 5018

Answers (2)

masokaya
masokaya

Reputation: 625

I am late, but it may help someone check Jetnews sample app in GitHub, navigate like this

navController.navigate(JetnewsDestinations.HOME_ROUTE) {
            // Pop up to the start destination of the graph to
            // avoid building up a large stack of destinations
            // on the back stack as users select items
            popUpTo(navController.graph.findStartDestination().id) {
                saveState = true
            }
            // Avoid multiple copies of the same destination when
            // reselecting the same item
            launchSingleTop = true
            // Restore state when reselecting a previously selected item
            restoreState = true
        }

this avoid multiple back stack also restore state of previous opened destination

Upvotes: 7

Richard Onslow Roper
Richard Onslow Roper

Reputation: 6825

How do you know that it is a new screen? Let me guess, you must be looking at some state of the screen, for example, filled textfields would be empty, scrolled lists would be reset, checkboxes would be reset or something to this effect. You see it does not matter whether you are calling the stuff from the backstack. The thing is, the moment a Composable is no longer visible on screen, it is destroyed, resetting all the state to the default values. That is, it will always be recomposed upon navigation request. What you need here is to store all that state inside a viewmodel. Then, reference the state from the viewmodel itself. Create state variables in the viewmodel with default values, then always reference from the viewmodel itself. This way, upon recomposition, the data would be fetched from the vm, and it will still be the correct data since the vm is not destroyed.

Upvotes: 1

Related Questions