13

我有一个片段,它有自己的状态(选定的按钮等)。该状态在屏幕旋转时丢失。

包含片段的活动在 /res/layout/ 中具有纵向布局,在 /res/layout-land/ 中具有几乎相同的横向布局。两种布局都包含这样的片段:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">
    <fragment
        android:id="@+id/testFragment"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        class="au.com.x.y.TestFragment" />
...</LinearLayout>

我一直在测试的片段类是:

public class TestFragment extends android.support.v4.app.Fragment {
    private static final String TAG = "TestFragment";
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.i(TAG, "onCreate(): " + 
                (savedInstanceState != null ? "NOT NULL" : "NULL"));
    }
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        Log.i(TAG, "onActivityCreated(): " + 
                (savedInstanceState != null ? "NOT NULL" : "NULL"));
    }
    public void onSaveInstanceState(Bundle state) {
        super.onSaveInstanceState(state);
        Log.i(TAG, "onSaveInstanceState()");
        state.putString("saved_thing", "some_value");
    }
    public View onCreateView(
        LayoutInflater inflater,
        ViewGroup container,
        Bundle b) { ... }
}

请注意,我使用的是 3.0 之前的片段支持包,通过 ActionBarSherlock 引入。

LogCat 给了我:

BEFORE SCREEN ROTATION (PORTRAIT):
02-23 11:45:58.015: I/TestFragment(22629): onCreate(): NULL
02-23 11:45:58.015: I/TestFragment(22629): onCreateView()
02-23 11:45:58.035: I/TestFragment(22629): onActivityCreated(): NULL
AFTER SCREEN ROTATION (LANDSCAPE):
02-23 11:46:00.615: I/TestFragment(22629): onCreate(): NULL
02-23 11:46:00.615: I/TestFragment(22629): onCreateView()
02-23 11:46:00.635: I/TestFragment(22629): onActivityCreated(): NULL

如您所见,从不调用,并且片段始终在两者中都onSaveInstanceState()为 null和。savedInstanceStateonCreate()onActivityCreated()

我已经尝试myFragment.setRetainInstance(true)过我的活动onCreate(),但这并没有改变任何东西。

onSaveInstanceState()有一个@Override,所以我知道它不像错字那样愚蠢。

我查看了 ActionBarSherlock 示例之一(com.actionbarsherlock.sample.shakespeare),并且其中的片段onSaveInstanceState()正确调用了它们的方法。据我所知,该示例与我的代码完全一样——通过布局和布局 XML 包含的片段。我什至使用与我的主项目使用的完全相同版本的 ActionBarSherlock 构建了该示例,并且保存实例状态对于该示例来说效果很好。

如何在屏幕旋转时保留片段状态?为什么不onSaveInstanceState()叫?

4

2 回答 2

23

您可以启用myFragment.setRetainInstance(true)保留状态,但它会“自动”执行此操作,即它保留分配给您的类成员的值并且不使用 onSaveInstanceState(因此 savedInstanceState 始终为空)。

确保FragmentActivity承载此片段的 没有覆盖onSaveInstanceState,或者当它覆盖时它应该调用super.onSaveInstanceState(Bundle).

于 2012-02-23T16:10:39.073 回答
-1

如果片段在旋转时需要不同的布局资源,setRetainInstance(true)则不能使用。此页面显示片段的生命周期setRetainInstance(true)

最初的想法是onSaveInstanceState()用来保留所有成员的数据,就像一个常规的活动一样。但是,由于某种原因,onSaveInstanceState()并没有被调用。但FragmentActivity正如@Eric Kok 所建议的那样,这是正确的)。我找到的最佳解决方案是使用片段参数

请参阅Fyodor Volchyok解决方案,它很简单。就像在 onSaveInstanceState() 和onViewCreated() 中一样工作。outStatesavedInstanceState

于 2014-11-22T07:22:10.927 回答