保存和恢复嵌套片段中的状态

我阅读了许多已经处理过类似问题的帖子,但是还没有找到能完全回答我的问题的东西。

我有一个使用嵌套片段的Android应用程序(来自v4支持库)。 我有一个主要的片段活动,其中包含一个片段,该片段包含一个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始终为空。 我还应该指出,调用this.setRetainInstance()会抛出一个异常,指出:“不能保留嵌套在其他片段中的片段”。

我怎样才能妥善保存和恢复嵌套片段的状态?

如果使用setRetainInstance(true),那么bundle当然是null。

片段不会被破坏,只能从当前活动中分离出来,并附加到新的活动中。 只有在碎片被销毁的时候,你才会得到一个包含你在onSaveInstanceState中保存的值的包。

只要尝试删除setRetainInstance(true)。

这是父代片段保留时可能遇到的问题。

你可以试试这个: http : //ideaventure.blogspot.lu/2014/10/nested-retained-fragment-lost-state.html

但是我最好建议删除parentFragment上的setRetaining()。

似乎没有一个嵌套片段保留信息的简单方法。 我的解决方案是让父片段保持在Bund的映射上,并且在onCreate期间嵌套的片段得到它们自己的。 最大的问题是你不能有每个嵌套片段的多个实例。

例如(对不起,这是在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() } } 

我有类似的问题,并寻求解决这个问题的提示。 最终,我意识到,我的父母片段的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,并恢复到我想要的。