Android 旋转设备后,不显示带有setRetainInstanceState(true)的DialogFragment

Android 旋转设备后,不显示带有setRetainInstanceState(true)的DialogFragment,android,Android,我有一个关于DialogFragment的问题。我试图创建一个对话框,在设备旋转后保持其状态。这个对话框有一堆对适配器和其他较重对象的引用,我需要在旋转时保持这些引用,如果可能的话,不必使每个引用都可以打包或序列化,以便在重新创建原始活动时使用onSaveInstanceState保存和还原它们 我注意到DialogFragment上有一个名为setRetainInstance(boolean)的方法,它允许您在重新创建活动时保留DialogFragment实例。但是,当我现在旋转设备时,对话框

我有一个关于DialogFragment的问题。我试图创建一个对话框,在设备旋转后保持其状态。这个对话框有一堆对适配器和其他较重对象的引用,我需要在旋转时保持这些引用,如果可能的话,不必使每个引用都可以打包或序列化,以便在重新创建原始活动时使用onSaveInstanceState保存和还原它们

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

谢谢,
Mihai

您需要做的事情很少:

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

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

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

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

  • 通过使用

    (MyModel) getArguments().getSerializable("MODEL")
    

  • 只要执行以下操作,对话框片段应自动保留:

  • 如果在SaveInstanceState()上调用活动,请确保调用超级函数。对我来说,这是关键。还要确保在片段中执行相同的操作
  • 如果使用
    setRetainInstance
    ,则需要手动存储这些值。否则,在大多数情况下,您应该不必担心它。如果您正在做一些更复杂的事情,您可能需要
    setRetainInstance(true)
    ,否则将忽略它
  • 一些人抱怨支持库中有一个bug,在不应该的时候会发送一条discouse消息。最新的支持库似乎已经解决了这一问题,因此您不必担心这一点

  • 也许这会有所帮助:我看到了一个更大的概念问题。android docs for setFragmentInstance中写到“控制在活动重新创建期间(例如从配置更改)是否保留片段实例。这只能用于不在后堆栈中的片段。如果设置了,则在重新创建活动时片段生命周期将略有不同”。这是因为对话片段在后台吗?谢谢@ricky888的回答,但是因为我正在创建一个对话片段实例并在对话片段的构造函数中传递内容,比如列表适配器和其他重数据,我想避免序列化,并考虑使用set retain instance state,这样对话框片段就不会在旋转时被重新创建。因此,我认为通过使用set retain instance state,我将拥有与旋转之前相同的对话框片段——这意味着在旋转时,对话框片段不会与活动及其片段一起重新创建。是这样吗?setRetainInstance-控制是否在活动重新创建期间(例如从配置更改)保留片段实例。所以答案是肯定的。正如我前面提到的,你只需将所有物品放入捆绑包,就可以在整个循环中保持它们的相同实例。事实上,正确的答案将涉及序列化,因此我们将片段重新设计为数据密集度较低的片段,以便能够在配置更改时保持其状态,正如@ricky888About#2所建议的,我认为您在句首的意思是“如果不使用setRetainInstance…”,因为否则您必须存储和恢复值。