【问题标题】:Prevent back button from closing a dialog box防止后退按钮关闭对话框
【发布时间】:2012-08-22 10:51:42
【问题描述】:

我试图阻止在 Android 中按下后退按钮时关闭 AlertDialog 框。我遵循了两种流行的方法in this thread,并且使用 System.out.println 我可以看到在这两种情况下代码都会执行。但是,返回按钮仍然关闭对话框。

我可能做错了什么?最终,我试图阻止后退按钮关闭对话框 - 这是第一次运行应用程序时显示的免责声明,我不希望用户有任何选择,只能按下“接受”按钮命令应用程序继续运行。

【问题讨论】:

  • 如果您要求用户接受许可或免责声明(或其他),那么您必须允许他们拒绝。如果他们单击BACK 按钮,请确保您的许可/免责声明对话框在他们下次启动应用程序时再次出现,并一次又一次地出现,直到他们接受或从设备中删除该应用程序。如果您选择使用 Sam 建议的方法,那么您必须提供一个“拒绝”按钮,然后在他们下次启动应用程序时重新创建许可/免责声明。
  • 我会删除一个让我“接受”作为唯一选项的应用程序......而且甚至不要考虑禁用主页按钮!
  • 应用程序可以通过按主页按钮关闭,但如果许可证不被接受,应用程序基本上无法通过免责声明。 @Squonk,你提到我必须允许他们拒绝;这是一个法律问题吗?即是否有法律规定软件必须在不接受许可协议的情况下才能使用(如果已付费)?注意我已经有一个“拒绝”按钮,按下它会弹出一个 Toast() 说您必须接受协议才能使用该应用程序。因此,对话框会一直存在,直到按下接受。
  • @CaptainProg :我不是律师,但我怀疑在某些国家/地区这可能被视为法律问题。如果他们拒绝/拒绝免责声明,我并不是建议您允许人们使用您的应用程序。我要说的是,这是糟糕的政策、糟糕的客户关系(即使应用程序是免费的),而且用户体验无法锁定某人。只需让“拒绝”选项关闭应用程序,下次用户尝试启动它,呈现相同的对话框。不要只是弹出Toast,将它们锁定并依靠它们使用HOME 按钮退出。

标签: android back


【解决方案1】:

只需使用setCancelable() 功能:

AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setCancelable(false);

这可以防止后退按钮关闭对话框,但如果您选择使用“否定”按钮,它会保持原样。


虽然任何不想接受您的服务条款的用户都可以按下主页按钮,但根据 Squonk 的评论,这里还有两种方法可以防止他们“退出”用户协议。一个是简单的“拒绝”按钮,另一个覆盖对话框中的后退按钮:

builder.setNegativeButton("Refuse", new OnClickListener() {
           @Override
           public void onClick(DialogInterface dialog, int which) {
               finish();
           }
       })
       .setOnKeyListener(new OnKeyListener() {
           @Override
           public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
               if(keyCode == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_UP)
                   finish();
               return false;
           }
       });

【讨论】:

  • 另外,如果使用DialogFragment,你应该调用setCancelable而不是Dialog本身
  • 非常感谢@Kuffs。我在对话框上设置它,想知道为什么它不起作用!
【解决方案2】:

为了防止后退按钮关闭一个Dialog(不依赖于Activity),只需如下代码:

alertDialog.setOnKeyListener(new DialogInterface.OnKeyListener() {
    @Override
    public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
        // Prevent dialog close on back press button
        return keyCode == KeyEvent.KEYCODE_BACK;
    }
});

【讨论】:

  • 在我的情况下工作得很好。我必须在我的应用程序上加载WebView。我必须检查canGoBack(),如果它是假的,就关闭对话框。
  • 运行良好。坚持下去
【解决方案3】:

使用DialogFragment 时,您需要在片段而不是对话框上调用setCancelable()

@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
    dialog = new ProgressDialog(getActivity());
    dialog.setIndeterminate(true);
    dialog.setMessage(...);
    setCancelable(false);

    return dialog;
}

调用dialog.setCancelable() 似乎没有任何效果。 DialogFragment 似乎没有注意到对话框的可取消性设置。

【讨论】:

    【解决方案4】:

    使用setCancelable(false)

    SampleDialog sampleDialog = SampleDialog.newInstance();
    sampleDialog.setCancelable(false);
    sampleDialog.show(getSupportFragmentManager(), SampleDialog.class.getSimpleName());
    

    【讨论】:

      【解决方案5】:

      只有这对我有用:

      AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
      builder.setTitle(title);
      builder.setMessage(content);
      
      /**
       * Make it when the Back button is pressed, the dialog isn't dismissed.
       */
      builder.setOnKeyListener(new DialogInterface.OnKeyListener() {
          @Override
          public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
              if(keyCode == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_UP) {
                  Utilities.makeToast(getContext(), "There is no way back!");
                  return true; // Consumed
              }
              else {
                  return false; // Not consumed
              }
          }
      });
      
      Dialog dialog = builder.create();
      
      /**
       * Make it so touching on the background activity doesn't close the dialog
       */
      dialog.setCanceledOnTouchOutside(false);
      
      return dialog;
      

      如您所见,我还添加了dialog.setCanceledOnTouchOutside(false); 行,因此在对话框外部点击也不会导致它被关闭。

      【讨论】:

        【解决方案6】:

        在 JQuery Mobile 中,弹出窗口会在 url 中添加一个哈希,以下代码允许后台在打开时关闭弹出窗口并在关闭时返回应用程序。您可以对自定义 ui 框架使用相同的逻辑。

        @Override
        public void onBackPressed() {
        
            // check if modal is open #&ui-state=dialog
        
            if (webView.getVisibility() == View.VISIBLE && webView.getUrl().contains("#&ui-state=dialog")) {
                // don't pass back button action
                if (webView.canGoBack()) {
                    webView.goBack();
                }
            } else {
                // pass back button action
                super.onBackPressed();
            }
        }
        

        【讨论】:

          【解决方案7】:

          添加setCancelable(false) 以阻止后退按钮关闭对话框。

          例如:

          AlertDialog.Builder builder = AlertDialog.Builder(this)
          Dialog dialog = builder.create()
          dialog.setCancelable(false)
          dialog.setCanceledOnTouchOutside(false)
          

          这将防止用户在按下后退按钮或触摸对话框窗口外时取消对话框

          【讨论】:

            猜你喜欢
            • 2011-10-30
            • 1970-01-01
            • 2020-05-02
            • 1970-01-01
            • 1970-01-01
            • 2018-09-23
            • 2022-01-06
            相关资源
            最近更新 更多