OnCancelListener 在 DialogFragment 中未被调用

我有一个显示某些项目列表的简单项目,单击其中一个时,单击的项目将传递回封闭项。我还想在用户取消对话框时执行一些默认处理(使用后退按钮) - 更具体地说,在这种情况下,我想将空字符串传递给活动。AlertDialogActivity

但是,如果将对话框放在(从兼容性包中)中,则当我使用后退按钮关闭对话框时,不会调用 。我做错了什么?DialogFragmentOnCancelListener

public class SelectItemDialog extends DialogFragment {

    public interface Callback {
        void onItemSelected(String string);
    }

    private static final String ARG_ITEMS = "items";

    private Callback callback;

    public static SelectItemDialog fromItems(Collection<String> items) {
        SelectItemDialog fragment = new SelectItemDialog();
        fragment.setArguments(newArguments(items));
        return fragment;
    }

    private static Bundle newArguments(Collection<String> items) {
        Bundle arguments = new Bundle();
        arguments.putStringArray(ARG_ITEMS, items.toArray(new String[items.size()]));
        return arguments;
    }

    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        callback = (Callback) activity;
    }

    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        final String[] items = getArguments().getStringArray(ARG_ITEMS);
        return new AlertDialog.Builder(getActivity())
            .setTitle(R.string.dialog_select_email_title)
            .setItems(items, new OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    callback.onItemSelected(items[which]);
                }
            })
            .setOnCancelListener(new OnCancelListener() {
                @Override
                public void onCancel(DialogInterface dialog) {
                    // this code is not executed
                    callback.onItemSelected("");
                    throw new RuntimeException("dialog cancelled");
                }
            })
            .create();
    }
}

答案 1

这可能与没有从代码显式调用有关。OnCancelListener 文档说:cancel()

仅当对话框被取消时才会调用

这可能需要显式调用。cancel()

使用调用 DialogInterface#cancel() 的 一个正/否定按钮,或者使用 OnDismissListener() 和一个额外的检查来查看是否单击了列表项。OnClickListener

此外,要侦听后退键并取消对话框,您可以设置一个 OnKeyListener,如 SO 答案中所述

此外,一旦你设置了Dialog,使用Dialog#setCanceledOnTouchOutside()也是一个好主意,以防用户点击对话框外部。

编辑:以下部分是处理DialogFragment中取消事件的简单方法。

由于您正在使用,因此此类有一个非常方便的方法,DialogFragment#onCancel()在取消时被调用。在那里做你的逻辑。DialogFragmentDialogFragment

DialogFragments 更为复杂,其生命周期与普通对话框略有不同。因此,如果您有某种基于的方法尝试移植到 ,则首先检查文档,这些方法可能允许您的新实现正常运行!DialogDialogFragment


答案 2

如果您使用的是DialogFragment,并且想要收听后退按钮,请使用这个 -

    this.getDialog().setOnKeyListener(new Dialog.OnKeyListener() {
        @Override
        public boolean onKey(DialogInterface dialog, int keyCode,
                KeyEvent event) {
            if (keyCode == KeyEvent.KEYCODE_BACK) {
                if (****) {
                    your logic
                }
                return true;
            }
            return false;
        }
    });

推荐