【问题标题】:Android DialogFragment disappears after orientation change方向更改后Android DialogFragment消失
【发布时间】:2012-09-14 23:57:39
【问题描述】:

我有一个 FragmentActivity 支持 v4 类,它实现了两个并排(有点像 gmail)片段和一个可以调出 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();
        }
    }

【问题讨论】:

    标签: android android-fragments android-lifecycle android-dialogfragment


    【解决方案1】:

    好的,所以问题似乎出在DialogFragment 兼容性库上。

    this 帖子中描述了该问题。

    “片段的过时 DISMISS 消息保留在消息队列中。在关闭旧对话框时它已由 DialogFragment.onDestroyView() 排队,并在创建新对话框后重新激活。

    一个快速(可能是肮脏的)解决方法是在调用super.onDestroyView()之前覆盖onDestroyView()并清除关闭侦听器“

    将以下代码添加到我的 DialogFragment 解决了这个问题:

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

    【讨论】:

      【解决方案2】:

      为了那些因不同原因遇到相同问题的可怜人(我)的利益,我将发布此内容。只要您执行以下操作,对话框片段就会自动保留:

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

      您不需要做任何花哨的事情,例如手动存储片段,如果您按照这些步骤操作,它应该会自动完成。总的来说,这似乎对任何拥有更现代的支持库的人都有效。

      【讨论】:

        【解决方案3】:

        在我的例子中,我有一个 DialogFragment 显示另一个 DialogFragment 使用

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

        改成

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

        修复了问题

        【讨论】:

        • 请注意您的更改与调用listDialogFragment.show(getFragmentManager(), "TAG"); 完全相同
        【解决方案4】:

        除了设置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);
            }
        }
        

        【讨论】:

        • 它在方向改变时创建多个对话框。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多