Android Fragment Lifecycle Over Orientation Changes

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).

Activity and Fragment Lifecycles and Orientation Changes

This happens because the activity calls onSaveInstanceState(Bundle) before being destroyed. By default, the activity is saving the states of its fragments in this method.

Later, when the activity is re-created, the old fragments are re-created in the activity onCreate(Bundle savedInstanceState) method.

You might want to check the source code here and here to better understand this behaviour.

Effect of change of orientation on Fragments

Yes, normally Fragments have similar lifecycle events as activities do. They also get destroyed and recreated on orientation change.

But it is possible to set a fragment to retain instance, which means that it survives the orientation change via the setRetainInstance(boolean) methode. This introduces quite a lot of new problems, but sometimes it is still the way to go.

Fragment loads multiple times on orientation change

When activity orientation changes, it will call onCreate() again and the fragment you have put into it will be recreated as well. In this case, you should create fragment on activity's first load only. Then get the saved fragment instance on the next load. Use tag as the Fragment key.

private static final String FRAGMENT_TAG = "fragmentOne";

private Fragment fragment;

protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_settings)

// savedInstanceState always null on activity's first load
if (savedInstanceState == null) {
fragment = new FragmentOne();
} else {
fragment = getSupportFragmentManager().findFragmentByTag(FRAGMENT_TAG);
}

getSupportFragmentManager().beginTransaction()
.replace(R.id.main_container, fragment, FRAGMENT_TAG)
.commit();
}


Related Topics



Leave a reply



Submit