Search code examples
androidandroid-jetpack-composeandroid-jetpack-navigation

How to keep navigation state with Compose Destination?


class BaseActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent { 
            MyTheme {
                DestinationsNavHost(
                    navGraph = NavGraphs.root,
                    startRoute = FirstScreenDestination
                )
            }
        }
    }
}

I use Compose Destination like this. When the Activity is destroyed and then restored, the navigation goes back to the very first screen. How can I save the current navigation state across activity/process death?


Solution

  • use the NavHostController

    val navController = rememberNavController()
    NavHost(
        navController = navController,
        startDestination = FirstScreenDestination
    ) {
        // your composable destinations here
    }
    

    save the state

    override fun onSaveInstanceState(outState: Bundle) {
        super.onSaveInstanceState(outState)
        navController.saveState() // this is where you save the state of the navController
    }
    

    restore the state

    val restoredState = savedInstanceState?.getParcelable<Bundle>("nav_state")
    val navController = rememberNavController()
    navController.restoreState(restoredState)
    

    save onSaveInstanceState

    outState.putParcelable("nav_state", navController.saveState())
    

    Using NavHost with the navController:

    NavHost(
        navController = navController,
        startDestination = FirstScreenDestination
    ) {
        // your composable destinations here
    }
    

    baseActivity

    class BaseActivity : AppCompatActivity() {
       
       private lateinit var navController: NavHostController
    
       override fun onCreate(savedInstanceState: Bundle?) {
           super.onCreate(savedInstanceState)
           
           val restoredState = savedInstanceState?.getParcelable<Bundle>("nav_state")
    
           setContent {
               MyTheme {
                   navController = rememberNavController()
                   navController.restoreState(restoredState)
    
                   NavHost(
                       navController = navController,
                       startDestination = FirstScreenDestination
                   ) {
                       // your composable destinations here
                   }
               }
           }
       }
    
       override fun onSaveInstanceState(outState: Bundle) {
           super.onSaveInstanceState(outState)
           outState.putParcelable("nav_state", navController.saveState())
       }
    }