是否有另一种保存嵌套片段状态的方法? 或者,如果我们不这样做,为什么?谢谢!
02-13 11:42:43.258: E/AndroidRuntime(7167): java.lang.IllegalStateException: Can't retain fragements that are nested in other fragments
02-13 11:42:43.258: E/AndroidRuntime(7167): at android.support.v4.app.Fragment.setRetainInstance(Fragment.java:742)
答案 0 :(得分:8)
您可以使用FragmentManager.saveFragmentInstanceState(Fragment)
来检索片段状态。返回值实现了Parcelable,因此您可以将它放在Bundle中。
对于恢复,您可以在使用Fragment.setInitialSavedState(Fragment.SavedState)
创建片段后提供状态。
答案 1 :(得分:8)
由于支持库20+(https://code.google.com/p/android/issues/detail?id=74222),有一个针对子片段的实例重新创建的错误,有一个修复它 - http://ideaventure.blogspot.com.au/2014/10/nested-retained-fragment-lost-state.html
网页上的代码(将其添加到您的父级片段) -
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);
}
答案 2 :(得分:2)
问题: mChildFrgamentManager
正在重新创建(https://code.google.com/p/android/issues/detail?id=74222)
解决方法:如果片段有mChildFrgamentManager
,则保留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();
}
}
}
警告:使用此代码,setRetainInstace
之前应调用onAttach
。
P.S:这是@attels答案的一点改进版本。
答案 3 :(得分:2)
在此AOSP commit之后,这不再是最新支持库的限制。
以下是提交消息:
允许嵌套片段上的setRetainInstance(true)
在配置更改中保存任意嵌套的片段为 非配置对象。这允许使用retain-instance 子片段作为其他内容中的任意不透明依赖项 片段。