13

还有另一种保存嵌套片段状态的方法吗?或者如果我们不应该这样做,为什么?谢谢 !

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

4 回答 4

9

您可以使用FragmentManager.saveFragmentInstanceState(Fragment)来检索片段状态。返回值实现了 Parcelable,所以你可以把它放在一个 Bundle 中。

对于恢复,您可以使用创建片段后的状态Fragment.setInitialSavedState(Fragment.SavedState)

于 2013-02-13T10:11:22.543 回答
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);

    }
于 2015-01-28T08:29:59.217 回答
3

在此AOSP 提交之后,这不再是最新支持库的限制。

以下是提交消息:

允许嵌套片段上的 setRetainInstance(true)

将配置更改中的任意嵌套片段保存为非配置对象。这允许将保留实例子片段用作其他片段中的任意不透明依赖项。

于 2016-10-19T12:36:48.813 回答
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

PS:这是@attels 答案的一些改进版本。

于 2015-08-05T13:08:55.383 回答