androidandroid-architecture-componentsandroid-jetpackandroid-architecture-navigationonconfigurationchanged

Android navigation component resets to start destination after configuration change


I am using the Android navigation component and I have an activity with three fragments if I am in the second fragment and rotate the screen forcing the activity to restart the navigation is returned to the start destination.

shouldn't the navhostFragment retain the state of the graph when the activity restarts?

or is what is happening the default behavior here?

I don't want to add the following even though adding it "works"

 android:configChanges="orientation|screenSize|screenLayout|keyboardHidden"

because I don't want to handle orientation changes myself, I want it to be handled by the system normally and still retain the navigation state

I will provide some of my code if that helps

in the activity I use navController.setGraph() so I can pass data to the start destination like this

 navController = Navigation.findNavController(
        this,
        R.id.nav_host_fragment
    )
 setSupportActionBar(findViewById(R.id.toolbar))
 appBarConfiguration = AppBarConfiguration.Builder(navController.graph).build()
 supportActionBar?.setDisplayHomeAsUpEnabled(true)

 intent.putExtra("EXTRA_KEY","some_data")
 navController.setGraph(R.navigation.nav_graph,intent.extras)

and I navigate from fragment to fragment using this

navController.navigate(FirstFragmentDirections.actionFirstFragmentToSecondFragment())

here is the code in the nav_graph

<fragment
    android:id="@+id/FirstFragment"
    android:name="com.example.app.presentation.ui.FirstFragment"
    android:label="FirstFragment" >
    <action
        android:id="@+id/action_FirstFragment_to_secondFragment"
        app:destination="@id/secondFragment"
        app:enterAnim="@anim/enter_from_right"
        app:exitAnim="@anim/exit_to_left"
        app:popEnterAnim="@anim/enter_from_left"
        app:popExitAnim="@anim/exit_to_right"
        />
</fragment>
<fragment
    android:id="@+id/secondFragment"
    android:name="com.example.app.presentation.ui.secondFragment"
    android:label="secondFragment"
    tools:layout="@layout/fragment_second" />

any help is appreciated thank you


Solution

  • You should generally never need to call setGraph() yourself, but you can workaround it like so in this particular case (and it will actually still work as you expect, because NavController / Navigator restores state properly across config changes and process death automatically):

    if (savedInstanceState == null) {
        navController.setGraph(R.navigation.nav_graph,intent.extras)
    }