【问题标题】:SavedInstanceState is always null in fragmentSavedInstanceState 在片段中始终为空
【发布时间】:2013-12-31 05:58:09
【问题描述】:

我有一个使用 XML 附加到活动的片段(以及活动中的 setContentView())。 A 有一个问题,因为我的片段中有非常动态的视图,所以当方向改变时 我必须恢复所有的观点状态。

我遇到了问题,因为我正在使用类似的东西:

public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putBoolean("restore", true);
        outState.putInt("nAndroids", 2);
   }

但是在调用带有参数 Bundle savedInstanceState 的方法(如 onCreateView 等)时方向更改后,我的 savedInstanceState 始终为空。

我不是 Android 的菜鸟,但现在因为这个问题我很生气......

public void onViewCreated(View view, Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);

    if (savedInstanceState == null) {
        //smth
    } else {
        // smthelse THIS IS NEVER REACHED BECAUSE BUNDLE IS ALWAYS NULL
    }

    getListView().setDivider(getResources().getDrawable(R.drawable.list_divider));
}

【问题讨论】:

  • Activity 中的相同内容可以正常工作(使用活动方法 onSaveInstance 状态)-我只对附加在 xml 布局中的片段中保存的捆绑包有问题...
  • 您可以在片段中的 OnCreate 上发布您的代码吗?
  • 我在文章末尾添加了。
  • @TommyNecessary "我不是 Android 的菜鸟,但现在因为这个问题我很生气......" :>

标签: android fragment bundle


【解决方案1】:

所有问题都在于我没有为 XML 中的片段声明 android:id。 Android 需要 ID 或 TAG 来识别存储的片段并复制其中的所有元素。所以伙计们,请记住 - 每个片段实例都需要唯一的 id 或标签!

此外,当声明 setRetainInstance(true) 时,bundle 应始终返回 null。

【讨论】:

  • 您能展示一下您的代码的外观吗?不确定如何/在何处将 xml ID 连接到片段活动。
  • 能否请您说明如何在 xml 中指定片段 ID。
  • @babay:很简单:
  • 谢谢。但是动态添加的片段(使用 FragmentManager 事务添加)呢?我发现的唯一方法是将状态存储在 Fragment 的参数中......
  • 回答@babay 关于以编程方式/动态添加片段的问题时,我遇到了同样的问题:每次我尝试恢复标准的 savedInstanceState 时,它​​总是为空。原因是因为我使用的是 popBackStack,所以 onSaveInstanceState 方法永远不会被调用,因为它在 onDestroy 之后而不是在 onDestroyView 之后,因此在 Fragment 中 savedInstanceState 始终为 null。所以解决方案很简单:创建一个私有 Bundle,您可以在 onPause 中保存 View 的状态,然后在 onCreateView 中恢复它。
【解决方案2】:

我遇到了类似的问题,尽管将 bundle 提供给 Fragment,但我总是将 savedInstanceState 设为 null。

对我有用的唯一解决方案是做

myFragment.setArguments(bundle) 

用我的 Activity 包做一个

Bundle bundle = this.getArguments();

在片段的 onCreateView 中。

希望这对其他人有所帮助。

【讨论】:

  • WTF,如果您从活动中设置参数,savedInstanceState 将始终返回 null。 Activity 包与 savedInstanceState 包无关。
【解决方案3】:

对于片段:-

use this for save state of fragment on orientation.

onCreate(Bundle save)
{
   super.onCreate(save);
   setRetainInstance(true);
}

请参阅本教程:- http://techbandhu.wordpress.com/2013/07/02/android-headless-fragment/

对于活动:-

当您启动应用程序时,在 onCreate 中,您的 bundle 对象为 null,因此您必须进行如下检查,当您旋转屏幕时,将调用 onSaveInstance 并初始化您的 bundle 对象

    @Override
    protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_game);

    if (savedInstanceState != null) {
         boolean t = outState.getBoolean("restore"); 
         int s = outState.getInt("nAndroids");
    }
}

【讨论】:

  • 我明白这一点,但我在活动实例中没有这个问题。当我像你一样做某事时,我从捆绑包中获得了很好的值,但在片段中的相同情况下,即使我将值放在片段实例中的 onSavedInstanceState 方法中,我也保存了 null。
【解决方案4】:

首先你应该输入你的数据,然后调用super.onSaveInstanceState(outState);

public void onSaveInstanceState(Bundle outState) {

    outState.putBoolean("restore", true);
    outState.putInt("nAndroids", 2);
    super.onSaveInstanceState(outState);
}

并确保活动在AndroidManifest.xml 中没有nohistory 属性或将其设置为false

        <activity
        android:noHistory="false">

【讨论】:

    【解决方案5】:

    如果您尝试使用 outState 保存状态并通过导航到另一个片段来销毁片段,它将不起作用,在这种情况下,您必须将状态永久保存在 sharedPreferences 中,或者如果它很大并且您想要更有条理,您可以使用任何持久性库,例如 Room、Realm 等。

    何时应仅使用 outState 和 savedInstanceState 来使 Fargment/Activity 在配置更改(例如旋转)或当应用处于后台时被操作系统杀死的进程中存活。

    【讨论】:

      【解决方案6】:

      好的,我知道这是一篇旧帖子,但我在这里或许多其他地方都找不到适合我的答案,所以我发布了我如何解决我的问题。

      所以我的片段在一个活动中。而且我最初尝试将Bundle仅保存在Fragment中并在onCreateView中检索它。然而这就是问题所在。

      我通过在活动中启动 myFragment 对象并在 onSaveInstanceState() 处将该对象放入活动包来解决此问题。然后在 onRestoreInstanceState() 中检索它。我使用了 getSupportFragmentManager().putFragment/getFragment。那么fragment中的savedInstanceState就不再是null了。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-02-21
        • 2019-09-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-06-19
        • 2022-01-15
        • 1970-01-01
        相关资源
        最近更新 更多