我阅读了许多已经处理过类似问题的帖子,但我们找不到能完全回答我问题的内容。
我有一个使用嵌套片段的Android应用程序(来自v4支持库)。我有一个包含片段的主FragmentActivity,该片段包含一个ViewPager,可以在3个内部片段之间滑动。 我希望能够保存3个内部嵌套片段中每个片段的状态,为此,我为3个内部片段中的每个片段覆盖了onSaveInstanceState()方法,并尝试在onActivityCreated()中恢复状态,像这样:
InternalFragment1.java:
public class InternalFragment1 extends Fragment {
@Override
public void onActivityCreated(Bundle savedInstanceState)
{
super.onActivityCreated(savedInstanceState);
// Commands to attach to main UI components...
if(savedInstanceState != null) {
// Commands to restore the saved state...
}
}
@Override
public void onSaveInstanceState(Bundle outState) {
// Commands to save the state into outState...
super.onSaveInstanceState(outState);
}
}
但是,当调用onActivityCreated()
时,无论是否存在已保存的状态,savedInstanceState始终为null。
我还应该指出,调用this.setRetainInstance()
会引发异常,说明:"不能保留嵌套在其他片段中的片段"。
如何正确保存和恢复嵌套片段'状态?
答案 0 :(得分:1)
如果你使用setRetainInstance(true),那么bundle当然是null。
片段不会被破坏,只会从当前活动中分离并附加到新活动。只有当片段被销毁时,才会获得一个包含你在onSaveInstanceState中保存的值的包。
尝试删除setRetainInstance(true)。
答案 1 :(得分:0)
这是父片段保留时可能遇到的问题。
你可以试试这个: http://ideaventure.blogspot.lu/2014/10/nested-retained-fragment-lost-state.html
但我最好建议删除parentFragment上的setRetaining()。
答案 2 :(得分:0)
嵌套片段似乎没有一种简单的方法来保留信息。我的解决方案是让父片段保持在Bundles的映射上,并且嵌套的片段在onCreate期间获得它们自己的片段。最大的问题是每个嵌套片段不能有多个实例。
Ex(对不起,这是在Kotlin,但在Java中也是如此)
class ParentFragment : Fragment(), ParentFragmentListener {
val bundles = SparseArray<Bundle>()
fun getChildBundle(fragmentId : Int) : Bundle {
if (bundles.get(fragmentId) == null) {
val bundle = Bundle()
bundles.put(fragmentId,bundle)
return bundle
}
return bundles.get(fragmentId)
}
}
interface ParentFragmentListener {
fun getChildBundle(fragmentId : Int) : Bundle
}
class ChildFragment : Fragment() {
lateinit var childBundle : Bundle
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val listener = parentFragment as? ParentFragmentListener
val childBundle = listener?.getFragmentsSavedBundle(UNIQUE_FRAGMENT_ID)
if (childBundle != null) this.childBundle = childBundle else childBundle = Bundle()
}
}
答案 3 :(得分:0)
我有一个类似的问题,正在寻找解决它的提示。最后,我意识到我的父片段的onCreateView包括:
mChildFragment = ChildFragment.newInstance(mId);
FragmentTransaction transaction = getChildFragmentManager().beginTransaction();
transaction.replace(R.id.fragment_container, mChildFragment).commit();
当然,这会创建子片段的新实例,该实例具有savedInstanceState的空包。用条件围绕上面的块:
if(savedInstanceState == null) {
mChildFragment = ChildFragment.newInstance(mId);
FragmentTransaction transaction = getChildFragmentManager().beginTransaction();
transaction.replace(R.id.fragment_container, mChildFragment).commit();
}
似乎使它工作,因为现在子片段中的onCreate看到我在onSaveInstanceState中为它创建的非null savedInstanceState,并恢复到我想要的状态。