【问题标题】:DialogFragment with setRetainInstanceState(true) is not displayed after the device is rotated旋转设备后不显示带有 setRetainInstanceState(true) 的 DialogFragment
【发布时间】:2012-12-18 14:20:47
【问题描述】:

我有一个关于 DialogFragment 的问题。我正在尝试制作一个对话框,在设备旋转后保持其状态。这个对话框有一堆对诸如适配器和其他较重对象之类的东西的引用,我需要在旋转时保持它,如果可能的话,不必将每个引用都设为 Parcelable 或 Serializable 以便我使用 onSaveInstanceState 来保存和恢复它们原始活动被重新创建。

我注意到 DialogFragment 上有一个名为 setRetainInstance(boolean) 的方法,它允许您在重新创建活动时保留对话框片段实例。但是,当我现在旋转设备时,对话框不再显示。我知道我可以从活动的 FragmentManager 中获取它,但我找不到让它再次可见的方法。对此有何建议?

谢谢, 米海

【问题讨论】:

  • 也许这会有所帮助:stackoverflow.com/questions/8235080/…
  • 我在这里看到了一个更大的概念问题。在 setFragmentInstance 的 android 文档中,它写道“控制是否在 Activity 重新创建期间保留片段实例(例如从配置更改中)。这只能与 不在后台堆栈中的片段一起使用. 如果设置,在重新创建活动时,片段生命周期将略有不同”。这是因为对话框片段在后台吗?

标签: android


【解决方案1】:

您需要做的事情很少:

  1. 使用实例工厂方法来启动 DialogFragment 实例,如下所示:

    public static MyDialogFragment newInstance(MyModel model) {
        MyDialogFragment myDialogFragment = new MyDialogFragment();
        Bundle bundle = new Bundle();
        bundle.putSerializable("MODEL", model);
        myDialogFragment .setArguments(bundle);
        return myDialogFragment;
    }
    
  2. 通过在 onCreate 中设置 setRetainInstance(true),在重新创建原始活动后,将保留在片段中声明的所有引用

    @Override
    public void onCreate(Bundle icicle) {
        this.setCancelable(true);
        setRetainInstance(true);
        super.onCreate(icicle);
    
    }
    
  3. 通过这样做避免在旋转时消失

    @Override
    public void onDestroyView() {
        if (getDialog() != null && getRetainInstance())
            getDialog().setDismissMessage(null);
        super.onDestroyView();
    

    }

  4. 使用

    获取您的对象
    (MyModel) getArguments().getSerializable("MODEL")
    

【讨论】:

  • 感谢@ricky888 的回答,但是由于我正在创建对话框片段实例并在对话框片段的构造函数中传递内容,例如列表适配器和其他重数据,因此我想避免序列化和我正在考虑使用设置保留实例状态,以便在旋转时不会重新创建对话框片段。因此,我认为通过使用设置保留实例状态,我将拥有与旋转之前相同的对话片段 - 这意味着对话片段不会在旋转时与活动及其片段一起重新创建。是这样吗?
  • setRetainInstance - 控制片段实例是否在 Activity 重新创建期间保留(例如从配置更改)。所以答案是肯定的。就像我上面提到的那样,只需将它们放在捆绑包中,您就可以在整个轮换中保持所有东西的相同实例。
  • 确实正确的答案将涉及序列化,因此我们重新设计了片段以减少数据密集度,以便能够在配置更改时保持其状态,正如@ricky888 所建议的那样
【解决方案2】:

只要您执行以下操作,对话框片段就会自动保留:

  1. 如果您调用 Activity onSaveInstanceState(),请确保您调用了超级函数!!!!。就我而言,这是关键。还要确保你在 Fragment 中做同样的事情。
  2. 如果您使用setRetainInstance,则需要手动存储这些值。否则,在大多数情况下,您应该不必担心。如果您正在做一些更复杂的事情,您可能需要setRetainInstance(true),否则请忽略它。
  3. 有些人抱怨支持库中的一个错误,即在不应该发送关闭消息时发送。最新的支持库似乎已经解决了这个问题,所以您不必担心。

【讨论】:

  • 关于#2,我认为你的意思是“如果你不使用 setRetainInstance ...”在句子的开头,因为否则你必须存储和恢复值。
猜你喜欢
  • 1970-01-01
  • 2020-12-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-25
  • 2017-05-29
相关资源
最近更新 更多