Is there another way of saving the state of the nested fragment ? Or if we shouldn\'t do this, why ? Thanks !
02-13 11:42:43.258: E/AndroidRuntime(7167): ja
Problem: mChildFrgamentManager
is being recreated (https://code.google.com/p/android/issues/detail?id=74222)
Workaround: Retaining mChildFrgamentManager
if fragment has setRetainInstance(true)
:
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
if (getRetainInstance()) {
if (mRetainedChildFragmentManager != null) {
try {
Field childFMField = Fragment.class.getDeclaredField("mChildFragmentManager");
childFMField.setAccessible(true);
childFMField.set(this, mRetainedChildFragmentManager);
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
} else {
mRetainedChildFragmentManager = getChildFragmentManager();
}
}
}
Warning: With this code, setRetainInstace
should be called before onAttach
.
P.S: This is a bit improved version of @attels answer.
You can use FragmentManager.saveFragmentInstanceState(Fragment) to retrieve a fragment state. The return value implements Parcelable, so you can put it in a Bundle.
For restoration, you can provide the state after creating the fragment using Fragment.setInitialSavedState(Fragment.SavedState).
This is no longer a limitation with latest support library, after this AOSP commit.
Below is commit message:
Permit setRetainInstance(true) on nested fragments
Save arbitrarily nested fragments across config changes as nonconfiguration objects. This permits the use of retain-instance child fragments as arbitrary opaque dependencies within other fragments.
Since support library 20+ (https://code.google.com/p/android/issues/detail?id=74222), there is a bug with instance recreation for child Fragments, there is a fix for it - http://ideaventure.blogspot.com.au/2014/10/nested-retained-fragment-lost-state.html
Code from the webpage(add this to your parent Fragment) -
private FragmentManager childFragmentManager() {//!!!Use this instead of getFragmentManager, support library from 20+, has a bug that doesn't retain instance of nested fragments!!!!
if(mRetainedChildFragmentManager == null) {
mRetainedChildFragmentManager = getChildFragmentManager();
}
return mRetainedChildFragmentManager;
}
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
if (mRetainedChildFragmentManager != null) {
//restore the last retained child fragment manager to the new
//created fragment
try {
Field childFMField = Fragment.class.getDeclaredField("mChildFragmentManager");
childFMField.setAccessible(true);
childFMField.set(this, mRetainedChildFragmentManager);
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRetainInstance(true);
}