33

我有一个FragmentActivity支持v4类,它实现了两个并排(有点像gmail)片段和一个可以调出DialogFragment的按钮。Android DialogFragment在方向转换后消失

这一切都很好,除非我改变方向。当我改变方向时,碎片的状态不会被保存。

而主要问题是如果我打开了FragmentDialog,它就会消失。

我已经在所有片段中设置了setRetainInstance(true);但它没有帮助。

在我的清单中,我包括android:configChanges="orientation",但仍然没有帮助。

这里是我的代码示例,谢谢你的帮助。

public class AddMasterDialog extends DialogFragment { 

    private int mTitle; 
    private int mPrompt; 
    private OnClickListener onSaveListener; 
    private OnClickListener onCancelListener; 

    public AddMasterDialog newInstance(int title, int prompt) { 
     AddMasterDialog simpleDialog = new AddMasterDialog(title, prompt); 
     return simpleDialog; 
    } 

    public AddMasterDialog() { 
     // Empty constructor required for DialogFragment 
    } 
    public AddMasterDialog(int title, int prompt) { 
     // Empty constructor required for DialogFragment 
     mTitle = title; 
     mPrompt = prompt; 
    } 
    public void setSaveButton(OnClickListener save){ 
     onSaveListener = save; 
    } 
    public void setCancelButton(OnClickListener cancel){ 
     onCancelListener = cancel; 
    } 
    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setRetainInstance(true); 
    } 

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

     //if(savedInstanceState == null){ 
      View view = inflater.inflate(R.layout.add_new_simple, container); 
      getDialog().setTitle(mTitle); 
      ((TextView) view.findViewById(R.id.add_simple_new_value_prompt)).setText(mPrompt); 

      Button saveButton = (Button) view.findViewById(R.id.add_simple_save_button); 
      saveButton.setOnClickListener(onSaveListener); 

      //Cancel Button 
      Button cancelButton = (Button) view.findViewById(R.id.add_simple_cancel_button); 
      cancelButton.setOnClickListener(onCancelListener); 
      return view; 
     //} 
    } 
} 

,并在我的主要活动:

private void initiateAddMasterPopupWindow() { 
     try { 
      addMasterDialog = new AddMasterDialog(R.string.add_new_master_dialog_title, R.string.add_master_new_value_prompt); 
      addMasterDialog.setSaveButton(saveNewMasterClickListener); 
      addMasterDialog.setCancelButton(cancelNewMasterClickListener); 
      FragmentManager fm = getSupportFragmentManager(); 
      addMasterDialog.show(fm, ADD_NEW_MASTER); 

     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
    } 

回答

70

好了,这个问题似乎是与DialogFragment兼容性库。

该问题在this后描述。

“的片段过时的解除消息保留在消息队列中。它是由DialogFragment.onDestroyView()解聘老对话框并创建新的对话框后,被重新激活时被排队。

快速(也可能是脏)的解决方法是覆盖onDestroyView(),并呼吁super.onDestroyView()

添加以下代码到我的DialogFragment之前清除解雇听众解决了这个问题:

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

酷修复,很好地工作。 –

13

为了可怜的灵魂(我)出于不同的原因有同样的问题,我将发布这个。对话片段应自动只要你做到以下保存:

  1. 如果您在呼叫Activity onSaveInstanceState()请确保调用父类的功能!!!!。就我而言,这是关键。还要确保你在片段中做同样的事情。
  2. 如果您使用setRetainInstance,则需要手动存储值并重新应用它们。否则,在大多数情况下,您应该无需担心。如果你做了一些更复杂的事情,你可能需要setRetainInstance(true),但否则忽略它。就我而言,我需要用它来为我的一个课程存储随机种子,但除此之外,我还可以。
  3. 有些人抱怨支持库中存在一个错误,当它不应该发送解雇消息时。最新的支持库似乎已经解决了这个问题,所以你不需要担心这一点。

您不应该像做手动存储碎片那样做任何花哨的事情,如果按照这些步骤操作,应该自动完成。总的来说,这似乎是为任何拥有更现代化支持库的人所做的诀窍。

+4

感谢您的第1步 – IHeartAndroid

1

除了设置setRetainInstance(true);只需将下面的代码放入您的DialogFragment。这是一个测试的解决方案。

private boolean isDismissible = false; 

@Override 
public void dismiss() { 

    try { 

     isDismissible = true; 
     super.dismiss(); 

     Log.d(getClass().getSimpleName(), "Dialog dismissed!"); 

    } catch (IllegalStateException ilse) { 
    } 
} 

@Override 
public void onDismiss(DialogInterface dialog) { 

    // So that dialog should not dismiss on orientation change 
    if (isDismissible) { 

     // So that dialog can be dismissed 
     super.onDismiss(dialog); 
    } 
} 
+0

它创建了多个方向更改对话框。 –

2

在我来说,我不得不表示另一DialogFragment使用

listDialogFragment.show(getChildFragmentManager(), "TAG"); 

改变它DialogFragment到

listDialogFragment.show(getActivity().getSupportFragmentManager(), "TAG"); 

固定问题

+0

注意你的改变与调用'listDialogFragment.show(getFragmentManager(),“TAG”);'' – William