Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android Fragment lifecycle over orientation changes

You're layering your Fragments one on top of the other.

When a config change occurs the old Fragment adds itself to the new Activity when it's recreated. This is a massive pain in the rear most of the time.

You can stop errors occurring by using the same Fragment rather than recreating a new one. Simply add this code:

if (savedInstanceState == null) {
    // only create fragment if activity is started for the first time
    mFragmentManager = getSupportFragmentManager();
    FragmentTransaction fragmentTransaction = mFragmentManager.beginTransaction();

    FragmentOne fragment = new FragmentOne();

    fragmentTransaction.add(R.id.fragment_container, fragment);
    fragmentTransaction.commit();
} else {        
    // do nothing - fragment is recreated automatically
}

Be warned though: problems will occur if you try and access Activity Views from inside the Fragment as the lifecycles will subtly change. (Getting Views from a parent Activity from a Fragment isn't easy).


To cite this book, "to ensure a consistent user experience, Android persists the Fragment layout and associated back stack when an Activity is restarted due to a configuration change." (p. 124)

And the way to approach that is to first check if the Fragment back stack has already been populated, and create the new fragment instance only if it hasn't:

@Override
public void onCreate(Bundle savedInstanceState) {

        ...    

    FragmentOne fragment = (FragmentOne) mFragmentManager.findFragmentById(R.id.fragment_container); 

    if (fragment == null) {
        FragmentTransaction fragmentTransaction = mFragmentManager.beginTransaction();
        fragmentTransaction.add(R.id.fragment_container, new FragmentOne());
        fragmentTransaction.commit();
    }
}

The onCreate() method of your activity is called after the orientation change as you have seen. So, do not execute the FragmentTransaction that adds the Fragment after the orientation change in your activity.

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    if (savedInstanceState==null) {
        //do your stuff
    }
}

The Fragments should and must be unchanged.


You can @Override the FragmentActivity using onSaveInstanceState(). Please be sure to not call the super.onSaveInstanceState() in the method.