【问题标题】:saveInstanceState is always nullsaveInstanceState 始终为空
【发布时间】:2015-10-03 19:31:02
【问题描述】:

我目前有一个附加到活动的片段。当我旋转我的设备时,希望在再次创建视图时保存和恢复网格的详细信息和位置。 onSavedStateInstance() 运行良好,我捆绑了所有内容,但是当调用片段的onCreateView() 时,stateInstance 为null。我知道之前有人问过并回答过类似的问题,但对我来说并没有真正的帮助。以下是一些可能对调试有用的 sn-ps。

MainActivityFragment

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {

    View view = inflater.inflate(R.layout.fragment_main, container, false);

    if (savedInstanceState != null) {
        gridViewObjects = (List<GridViewObject>) savedInstanceState.get(movieKey);
        position = savedInstanceState.getInt("position");
    } else {
        gridViewObjects = new ArrayList<>();
    }
    return view;
}

@Override
public void onSaveInstanceState(Bundle outState) {
    outState.putParcelableArrayList(movieKey, (ArrayList) gridViewObjects);
    outState.putInt("position", gridView.getFirstVisiblePosition());
    super.onSaveInstanceState(outState);
}

fragment_main.xml

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="app.sunshine.android.example.com.popmovies.MainActivityFragment">

    <GridView
        android:id="@+id/fragment_main_gridView"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:clickable="true"
        android:gravity="center"
        android:numColumns="2"
        android:stretchMode="columnWidth"
        android:verticalSpacing="5dp" />

</FrameLayout>

主活动

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    ActionBar actionBar = getSupportActionBar();
    actionBar.setBackgroundDrawable(new ColorDrawable(getResources().getColor(R.color.indigo_500)));
    setContentView(R.layout.activity_main);
}

编辑:在调试时,我看到在设备方向更改时,活动被重新创建,OnCreate() 方法中的 savedInstanceState 不为空。捆绑包详细信息完好无损。只有在创建fragment时,OnCreateView()中的savedInstanceState为null。

任何帮助表示赞赏!

【问题讨论】:

  • 我在代码中没有看到您尝试将任何键值对放入 savedInstanceState 的任何地方。调用 onConfigurationChanged() 从 bundle 中获取值
  • 感谢您指出。更新了帖子。
  • 您正在保存gridView.getFirstVisiblePosition() 的值,但您正在将其恢复到名为position 的字段中。这是你的意图吗?
  • @KevinKrumwiede 是的,我对这个职位所做的是:gridView.setSelection(position);
  • 你也可以发布 R.layout.activity_main 吗?如果片段没有 ID 或标签,则没有可保存的内容。

标签: android android-fragments android-activity


【解决方案1】:

试试这个

@Override
public void onRestoreInstanceState(Bundle savedInstanceState) {
  super.onRestoreInstanceState(savedInstanceState);    

         if (savedInstanceState != null) {
            gridViewObjects = (List<GridViewObject>) savedInstanceState.get(movieKey);
            position = savedInstanceState.getInt("position");
        } else {
            gridViewObjects = new ArrayList<>();
        }
    }

还有

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {

    View view = inflater.inflate(R.layout.fragment_main, null);
    return view;
}

【讨论】:

  • 谢谢,但这并没有帮助。这是正在发生的事情。在方向更改时,将再次创建活动。所以在 mainActivity(不是片段)上,实例不为空,我可以查看包的详细信息。但是在创建片段视图时(onCreateView),saveInstanceState 为空。
【解决方案2】:

在片段中,通过覆盖onSaveInstanceState保存实例状态并在onActivityCreated上恢复:

@Override
public void onActivityCreated(Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);
    ...
    if (savedInstanceState != null) {
        //Restore the fragment's state here
    }
}
...
@Override
public void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);

//Save the fragment's state here



}

很重要的一点,在活动中,你必须将片段的实例保存在onSaveInstanceState并恢复到onCreate

public void onCreate(Bundle savedInstanceState) {
    ...
    if (savedInstanceState != null) {
        //Restore the fragment's instance
        mContent = getSupportFragmentManager().getFragment(
                    savedInstanceState, "mContent");
        ...
    }
    ...
}

@Override
protected void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);

//Save the fragment's instance
getSupportFragmentManager().putFragment(outState, "mContent", mContent);



}

所以要正确保存 Fragment 的实例状态,您应该执行以下代码

【讨论】:

  • 我知道这个答案来自这里:stackoverflow.com/questions/15313598/… 你能告诉我如果接收到的 savedInstaceState 本身为空,它会如何工作吗?我的意思是,只有当 savedInstaceState 不为空时,我才能恢复片段(这不是我想要的)。
  • 当之前没有保存数据时,savedInstanceState 为空。要保存数据,您必须按照 Android 文档中的说明覆盖 onSaveInstanceStateBundle(Bundle) 方法:link
  • 是的,我明白这一点,这正是我所做的。我的理解是不需要保存整个片段状态。
猜你喜欢
  • 2017-07-31
  • 2019-07-18
  • 2019-08-18
  • 2011-12-29
  • 2019-07-02
  • 2019-05-04
  • 1970-01-01
  • 2011-05-04
  • 2015-10-29
相关资源
最近更新 更多