【问题标题】:Yes/NO Alert Dialog box in AndroidAndroid中的是/否警报对话框
【发布时间】:2012-07-30 04:23:24
【问题描述】:

我想在 android 的 onBackPressed() 事件上显示一个警报对话框

DialogInterface.OnClickListener dialogClickListener = new DialogInterface.OnClickListener() {

    //@Override
    public void onClick(DialogInterface dialog, int which) {
        switch (which){
        case DialogInterface.BUTTON_POSITIVE:
            //Yes button clicked
            break;

        case DialogInterface.BUTTON_NEGATIVE:
            //No button clicked
            break;
        }
    }
};

但在 onBackPressed() 事件中执行时出现错误

@Override
public void onBackPressed() {
    super.onBackPressed();  
    AlertDialog.Builder builder = new AlertDialog.Builder(this);
    builder.setMessage("Are you sure?").setPositiveButton("Yes", dialogClickListener)
        .setNegativeButton("No", dialogClickListener).show();

}

错误: "com.java.mypkg 泄露了最初添加在这里的窗口 com.android.internal.policy.impl.PhoneWindow$DecorView@406c3798"

我是否遗漏了什么。请帮忙。

【问题讨论】:

    标签: android


    【解决方案1】:

    是的,不要按照以前用户的响应调用它。 super.onBackPressed();onStop Activity 的方法。您可以使用 onKeyDown 代替 onBackPressed(); 来满足您的要求。如果您需要在按下返回按钮时打开AlertDialog,您可以简单地尝试使用KeyEvent

    例如——

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        // TODO Auto-generated method stub
    
        switch(keyCode)
        {
        case KeyEvent.KEYCODE_BACK:
            AlertDialog.Builder ab = new AlertDialog.Builder(AlertDialogExampleActivity.this);
            ab.setMessage("Are you sure?").setPositiveButton("Yes", dialogClickListener)
            .setNegativeButton("No", dialogClickListener).show();
            break;
        }
    
        return super.onKeyDown(keyCode, event);
    }
    
    DialogInterface.OnClickListener dialogClickListener = new DialogInterface.OnClickListener() {
        @Override
        public void onClick(DialogInterface dialog, int which) {
            switch (which){
            case DialogInterface.BUTTON_POSITIVE:
                //Yes button clicked
                break;
    
            case DialogInterface.BUTTON_NEGATIVE:
                //No button clicked
                break;
            }
        }
    };
    

    当您覆盖 onKeyDown 方法时,它将使用您的 KEYCODE_BACK 检测返回键

    希望对你有所帮助。

    【讨论】:

      【解决方案2】:

      不要调用super.onBackPressed();,因为它会调用活动的onStop方法。

      并且在已完成的活动上显示一个对话框,将泄漏窗口。

      【讨论】:

      • 感谢它的工作。但我想知道在哪种情况下我们必须使用 'super.onBackPressed();'事件
      • super.onBackPressed 必须调用,当你想在停止活动之前做一些操作,然后调用 super.onBackPressed() 调用默认操作 onBackPressed。
      【解决方案3】:
      1. 继续为这一行提供适当的上下文::

        AlertDialog.Builder builder = new AlertDialog.Builder(ActivityName.this);     
        
      2. 像这样适当地关闭警报对话框。

        new AlertDialog.Builder(ActivityName.this)  
        .setMessage("You have to Login first to apply.\nWant to login ?")  
        .setCancelable(false)  
        .setPositiveButton("Yes", new DialogInterface.OnClickListener() {  
            public void onClick(DialogInterface dialog, int which)   
            {  
                  // Perform Your Task Here--When Yes Is Pressed.  
                  dialog.cancel();  
            }  
        })    
        .setNegativeButton("No", new DialogInterface.OnClickListener() {  
              public void onClick(DialogInterface dialog, int which)   
              {  
             // Perform Your Task Here--When No is pressed    
                 dialog.cancel();  
              }  
        }).show();  
        

      Window leaked 的这个错误是在 ::

      时引起的
      • 在具有不同上下文的 Activity 中打开了一个新窗口 不同的上下文。

      • 退出 Activity 时未正确关闭窗口或对话框。

      【讨论】:

        【解决方案4】:

        我的 alertdialog 方法:

        public void message_dialog_yes_no (Activity activity, String msg, DialogInterface.OnClickListener yesListener) {
            AlertDialog.Builder builder = new AlertDialog.Builder(activity);
        
            builder.setMessage(msg)
                   .setCancelable(false)
                   .setPositiveButton("Yes", yesListener) 
                   .setNegativeButton("No",  new DialogInterface.OnClickListener() {
                       public void onClick(DialogInterface dialog, int id) {
                           dialog.cancel();
                      }})              
                   .show();
        }
        

        声明这个方法后,我可以这样调用它:

        DialogInterface.OnClickListener yesListener;
        
                yesListener = new DialogInterface.OnClickListener() {               
                    public void onClick(DialogInterface dialog, int which) {
        //codes
                }
                };
        
        message_dialog_yes_no(this, "Confirm delete?" , yesListener);
        

        【讨论】:

          【解决方案5】:

          如果您想执行默认操作(即实际返回)而不是想留在 Activity 中,则应该只调用 super.onBackPressed()

          有关如何正确覆盖 onBackPressed() 的示例,请参阅 this link

          【讨论】:

            【解决方案6】:

            我们通常会在退出 Activity 时重写onBackPressed() 来执行一些条件。这意味着我们实际上是通过正常执行的 Back Press 事件,这不过是super.onBackPressed。因此,将其包含在被覆盖的方法中意味着它也将遵循按下后退键时将执行的默认执行,并且我们自己的方法也将被执行。

            但在您的情况下,由于您在调用超类后尝试显示 AlertDialog,因此您的 Activity 上下文不再可用,这意味着您的 Alert Dialog 没有窗口可以显示自身,因此出现泄漏窗口错误。

            在这种情况下,您已经删除了超类调用。简单的。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2019-09-05
              • 2012-10-20
              • 1970-01-01
              • 1970-01-01
              • 2011-12-25
              • 1970-01-01
              相关资源
              最近更新 更多