Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Fragment Backstack is not restored when orientation changes

I have a FragmentActivity, when the user navigates through the app, I replace the current fragment with the fragment the user has selected and add add the transactions to backstack. Everything works fine, the user can go back to the previous fragments by pressing the back button.

The problem occurs when the device orientation changes: suppose the first fragment that the user sees is A, then he navigates to B and from B to C. The content inside of C is better appreciated in landscape mode, and there is a special landscape layout for C, so the user rotates the device. I would expect the user to be in C with the new orientation. Instead, the user sees A in landscape. Now he needs to navigate again from A to B and then to C, to be able to see C in landscape.

I want the backstack to be preserved after the orientation change.

If I use configChange="orientation" on my Activity's entry in the manifest, the backstack is preserved, but since the fragment is not recreated, it can't load the correct layout for the new orientation. I bet I could use some nasty hack to force the recreation of the fragment when this happens, but I think there should be a better solution to achieve something so simple.

Apparently I am doing something wrong, because in this page, there is an explanation that says

-> Fragment Manager invokes onSaveInstanceState() on both the fragments.
-> Activity and both Fragments are destroyed
-> New instance of the Activity is created
-> Back stack is recreated with new instances of the Fragments

Which sounds like the behavior I expect, but that doesn't happen in my app. Am I missing something? How can I achieve this behavior?

I have seen some similar questions on SO, but none of them helped me to solve this so far. Any help will be greatly appreciated.

like image 816
Alex Terreaux Avatar asked Sep 17 '15 18:09

Alex Terreaux


2 Answers

I think you're not checking the savedInstanceState before adding/replacing the fragment. Try this:

    @Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    // Check that the activity is using the layout version
    // with the fragment_container_main FrameLayout
    if (findViewById(R.id.fragment_container_main) != null) {


        // If we're being restored from a previous state,
        // then we don't need to do anything and should return or else
        // we could end up with overlapping fragments.
        if (savedInstanceState != null) { //Do nothing, Android has got your back.

        } else {
            FragmentOne fragmentOne = new FragmentOne();

            // Add the fragment to the fragment_container_main FrameLayout
            getFragmentManager().beginTransaction()
                    .add(R.id.fragment_container_main,
                            fragmentOne,
                            "FRAG_ONE").commit();
        }
    }
}
like image 195
Aditya Naique Avatar answered Sep 19 '22 16:09

Aditya Naique


Turns out the navigation drawer fragment was being recreated after the orientation change, so it triggered the onNavigationDrawerItemSelected, which always replaced the fragments that android was restoring. I fixed it by adding setRetainInstance(true); in my navigation drawer fragment.

like image 26
Alex Terreaux Avatar answered Sep 20 '22 16:09

Alex Terreaux