【问题标题】:setOnCancelListener and setOnDismissListener is not called for AlertDialog for back button pressed or touch outside没有为 AlertDialog 调用 setOnCancelListener 和 setOnDismissListener 来按下后退按钮或触摸外部
【发布时间】:2013-08-18 12:59:39
【问题描述】:

什么时候

  • 在对话框区域外触摸
  • 按下返回按钮

我期待onDismiss(或onCancel)会被调用。但是,它们都没有被调用。我可以知道我缺少什么吗?从AlertDialog setOnDismissListener not working,我认为当我按下返回按钮时会调用onCancel。但这对我不起作用。我可以知道我错过了什么吗?

public class RateAppDialogFragment extends SherlockDialogFragment {
    public static RateAppDialogFragment newInstance() {
        RateAppDialogFragment rateAppDialogFragment = new RateAppDialogFragment();
        return rateAppDialogFragment;
    }

    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        // Get the layout inflater
        LayoutInflater inflater = getActivity().getLayoutInflater();
        View view = inflater.inflate(R.layout.rate_app_dialog_fragment, null);

        Utils.setCustomTypeFace(view, Utils.ROBOTO_LIGHT_TYPE_FACE);

        final AlertDialog dialog = new AlertDialog.Builder(this.getSherlockActivity())            
        .setTitle("Love JStock?")
        .setView(view)
        // Add action buttons
        .setPositiveButton("Rate 5 stars \u2605", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int id) {
                Utils.showShortToast("Rate");
            }
        })
        .setNegativeButton("No", new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int id) {
                Utils.showShortToast("No");
            }
        })
        .setNeutralButton("Later", new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int id) {
                Utils.showShortToast("Later");
            }
        })
        .create();

        dialog.setCanceledOnTouchOutside(true);

        dialog.setOnCancelListener(new DialogInterface.OnCancelListener() {

            @Override
            public void onCancel(DialogInterface dialog) {
                Utils.showShortToast("Back button pressed?");
            }
        });

        dialog.setOnDismissListener(new DialogInterface.OnDismissListener() {

            @Override
            public void onDismiss(DialogInterface dialog) {
                // TODO Auto-generated method stub
                Utils.showShortToast("Back button pressed?");
            }
        });

        return dialog;
    }

}

    FragmentManager fm = fragmentActivity.getSupportFragmentManager();
    if (fm.findFragmentByTag(RATE_APP_DIALOG_FRAGMENT) != null) {
        return;
    }

    RateAppDialogFragment rateAppDialogFragment = RateAppDialogFragment.newInstance();
    rateAppDialogFragment.show(fm, RATE_APP_DIALOG_FRAGMENT);  

【问题讨论】:

  • @pskink 你在代码上测试运行吗?它真的适合你吗?
  • 我使用 Log.d。没有什么不同。吐司和日志消息都不会显示。
  • 我用最少的设置运行它 - 生成器只有正面和负面按钮,用 2.2 avd 测试
  • @pskink 如果您使用 DialogFragment,您会遇到问题。
  • 好的,现在看,但是 onCreateDialog 的文档解释了一切

标签: android


【解决方案1】:

如果您使用的是AlertDialog,请参阅

builder.setOnCancelListener(new DialogInterface.OnCancelListener() {
    @Override
    public void onCancel(DialogInterface dialog) {
        // dialog dismiss without button press
    }
});

dialog.setCanceledOnTouchOutside(true)(感谢@LeosLiterak)

【讨论】:

  • 并添加 dialog.setCanceledOnTouchOutside(true) 以及
  • java.lang.IllegalStateException: 不能设置 Dialog 的 OnCancelListener 或 OnDismissListener
  • 不要与构建器一起工作(至少对我来说),在 API 21 上测试。
  • @Joe 那是因为您将它与DialogFragment 一起使用(请参阅this question)。使用 AlertDialog,它正在工作。
【解决方案2】:

在您的 DialogFragment 中,覆盖

@Override
public void onStop() {
    super.onStop();
    if (mListener != null) {
       // do something here
    }
}

【讨论】:

    【解决方案3】:

    你还没有设置backPressed按键事件

    dialog.setOnKeyListener(new Dialog.OnKeyListener() {
        @Override
        public boolean onKey(DialogInterface arg0, int keyCode, KeyEvent event) {
            // TODO Auto-generated method stub
            if (keyCode == KeyEvent.KEYCODE_BACK) {
                finish();
            }
            return true;
        }
    });
    

    【讨论】:

    • 但是,在对话框区域之外触摸怎么样?另外,您知道为什么 setOnCancelListener 和 setOnDismissListener 不起作用吗?他们应该工作,不是吗?
    • 当你得到解决方案时。我会说这是一个又大又愚蠢的错误.. :D 如果您要覆盖默认方法,则必须在其上正确@override
    【解决方案4】:

    当您使用DialogFragment 显示Dialog 时会出现问题

    根据http://developer.android.com/reference/android/app/DialogFragment.html,解决方法是在DialogFragment中覆盖onCancel

    也请注意http://developer.android.com/reference/android/app/DialogFragment.html#onCreateDialog(android.os.Bundle)

    注意:DialogFragment 拥有 Dialog.setOnCancelListener 和 Dialog.setOnDismissListener 回调。你不能自己设置它们。 要了解这些事件,请覆盖 onCancel(DialogInterface) 和 onDismiss(DialogInterface)。

    // This is DialogFragment, not Dialog
    @Override
    public void onCancel(DialogInterface dialog) {
    }
    

    【讨论】:

    • 不错的解决方案!这实际上是在 DialogFragment 中使用 Cancel 的方式。
    • 如果你离开super.onCancel(dialog),它会起作用。我可以立即触发我的操作,而cancel 按钮最终不会有这个方法调用,这很好
    • @Cheok Yan Cheng 我有一个类似的用例,并根据您上面的建议设置了 onCancel()。有时需要在对话框外多次单击(我在 DilaogFragment 中使用 DatePickerDialog)才能最终关闭对话框。关于如何捕捉对话框外的第一次触摸以便我可以立即关闭对话框的任何想法?
    【解决方案5】:

    你应该阅读这个主题:How to dismiss the dialog with click on outside of the dialog?

    Dialog dialog = new Dialog(context)
    dialog.setCanceledOnTouchOutside(true);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-09-26
      • 2011-04-24
      • 1970-01-01
      • 1970-01-01
      • 2013-10-11
      相关资源
      最近更新 更多