Android对话框,按下按钮时保持对话框打开

时间:2011-05-26 17:03:06

标签: android dialog

当我按下按钮时,我想保持对话框打开。 目前正在关闭。

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

builder.setMessage("Are you sure you want to exit?")

   .setCancelable(false)
   .setPositiveButton("Yes", new DialogInterface.OnClickListener() {
       public void onClick(DialogInterface dialog, int id) {
            MyActivity.this.finish();
       }
   })
   .setNegativeButton("No", new DialogInterface.OnClickListener() {
       public void onClick(DialogInterface dialog, int id) {
            dialog.cancel();
       }
   });
AlertDialog alert = builder.create();

7 个答案:

答案 0 :(得分:91)

是的,你可以。你基本上需要:

  1. 使用 DialogBu​​ilder
  2. 创建对话框
  3. show()对话框
  4. 找到显示的对话框中的按钮并覆盖其onClickListener
  5. 所以,创建一个监听器类:

    class CustomListener implements View.OnClickListener {
      private final Dialog dialog;
    
      public CustomListener(Dialog dialog) {
        this.dialog = dialog;
      }
    
      @Override
      public void onClick(View v) {
    
        // Do whatever you want here
    
        // If you want to close the dialog, uncomment the line below
        //dialog.dismiss();
      }
    }
    

    然后在显示对话框时使用:

    AlertDialog dialog = dialogBuilder.create();
    dialog.show();
    Button theButton = dialog.getButton(DialogInterface.BUTTON_POSITIVE);
    theButton.setOnClickListener(new CustomListener(dialog));
    

    请记住,您需要显示对话框,否则将无法找到该按钮。此外,请务必将 DialogInterface.BUTTON_POSITIVE 更改为用于添加按钮的任何值。另请注意,在 DialogBu​​ilder 中添加按钮时,您需要提供onClickListeners - 您无法在其中添加自定义侦听器 - 如果您不覆盖,对话框仍会被忽略调用show()后的听众。

答案 1 :(得分:28)

感谢Sogger的回答,但是我们必须做一个改变,就是在创建对话框之前,我们应该将AlertDialog设置为正确的按钮(如果有需要的话,还可以设置为负按钮),就是这样。

Sogger引用。

以下是示例示例...

AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setMessage("Test for preventing dialog close");
        builder.setTitle("Test");

        builder.setPositiveButton("OK", new OnClickListener() {

            @Override
            public void onClick(DialogInterface dialog, int which) {
                // TODO Auto-generated method stub

            }
        });
    builder.setNegativeButton("Cancel", new OnClickListener() {

            @Override
            public void onClick(DialogInterface dialog, int which) {
                // TODO Auto-generated method stub

            }
        });

        final AlertDialog dialog = builder.create();
        dialog.show();
        //Overriding the handler immediately after show is probably a better approach than OnShowListener as described below
        dialog.getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener(new View.OnClickListener()
              {            
                  @Override
                  public void onClick(View v)
                  {
                      Boolean wantToCloseDialog = false;
                      //Do stuff, possibly set wantToCloseDialog to true then...
                      if(wantToCloseDialog)
                          dialog.dismiss();
                      //else dialog stays open. Make sure you have an obvious way to close the dialog especially if you set cancellable to false.
                  }
              });

        dialog.getButton(AlertDialog.BUTTON_NEGATIVE).setOnClickListener(new View.OnClickListener()
          {            
              @Override
              public void onClick(View v)
              {
                  Boolean wantToCloseDialog = true;
                  //Do stuff, possibly set wantToCloseDialog to true then...
                  if(wantToCloseDialog)
                      dialog.dismiss();
                  //else dialog stays open. Make sure you have an obvious way to close the dialog especially if you set cancellable to false.
              }
          });

答案 2 :(得分:13)

我相信@Kamen的答案是正确的,这里是使用匿名类的相同方法的一个例子,所以它只是在一个代码流中:

AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setMessage("Test for preventing dialog close");
AlertDialog dialog = builder.create();
dialog.show();
//Overriding the handler immediately after show is probably a better approach than OnShowListener as described below
dialog.getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener(new View.OnClickListener()
      {            
          @Override
          public void onClick(View v)
          {
              Boolean wantToCloseDialog = false;
              //Do stuff, possibly set wantToCloseDialog to true then...
              if(wantToCloseDialog)
                  dismiss();
              //else dialog stays open. Make sure you have an obvious way to close the dialog especially if you set cancellable to false.
          }
      });

我写了一篇更详细的文章来回答同一个问题https://stackoverflow.com/a/15619098/579234,其中还有其他对话框的例子,如DialogFragment和DialogPreference。

答案 3 :(得分:2)

这是我在更改密码时设置创建持久弹出窗口的方法。

// Login Activity
AlertDialog.Builder alert = new AlertDialog.Builder(this);
alert.SetIcon(Resource.Drawable.padlock);
alert.SetCancelable(false);

var changepass = LayoutInflater.From(this);
var changePassLayout = changepass.Inflate(Resource.Layout.ChangePasswordLayout, null);

alert.SetView(changePassLayout);

txtChangePassword = (EditText)changePassLayout.FindViewById(Resource.Id.txtChangePassword);
txtChangeRetypePassword = (EditText)changePassLayout.FindViewById(Resource.Id.txtChangeRetypePassword);

alert.SetPositiveButton("Change", delegate {
    // You can leave this blank because you override the OnClick event using your custom listener
});

alert.SetNegativeButton("Cancel", delegate {
    Toast.MakeText(this, "Change password aborted!", ToastLength.Short).Show();
});

AlertDialog changePassDialog = alert.Create();
changePassDialog.Show();

// Override OnClick of Positive Button
Button btnPositive = changePassDialog.GetButton((int)Android.Content.DialogButtonType.Positive);
btnPositive.SetOnClickListener(new CustomListener(changePassDialog, empDetailsToValidate.EmployeeID));

// My Custom Class
class CustomListener : Java.Lang.Object, View.IOnClickListener, IDialogInterfaceOnDismissListener
{
    AlertDialog _dialog;
    EditText txtChangePassword;
    EditText txtChangeRetypePassword;

    EmployeeDetails _empDetails;
    string _workingEmployeeID;

    public CustomListener(AlertDialog dialog, string employeeID)
    {
        this._dialog = dialog;
        this._workingEmployeeID = employeeID;
    }
    public void OnClick (View v)
    {
        _empDetails = new EmployeeDetails(v.Context);

        txtChangePassword = (EditText)_dialog.FindViewById (Resource.Id.txtChangePassword);
        txtChangeRetypePassword = (EditText)_dialog.FindViewById (Resource.Id.txtChangeRetypePassword);

        if (!(txtChangePassword.Text.Equals(txtChangeRetypePassword.Text))) {
            Show ();
            Toast.MakeText(v.Context, "Password not match.", ToastLength.Short).Show();
        } else if (txtChangePassword.Text.Trim().Length < 6) {
            Show ();
            Toast.MakeText(v.Context, "Minimum password length is 6 characters.", ToastLength.Short).Show();
        } else if ((txtChangePassword.Text.Equals(LoginActivity.defaultPassword)) || (txtChangePassword.Text == "" || txtChangeRetypePassword.Text == "")) {
            Show ();
            Toast.MakeText(v.Context, "Invalid password. Please use other password.", ToastLength.Short).Show();
        } else {
            int rowAffected = _empDetails.UpdatePassword(_workingEmployeeID, SensoryDB.PassCrypto(txtChangePassword.Text, true));
            if (rowAffected > 0) {
                Toast.MakeText(v.Context, "Password successfully changed!", ToastLength.Short).Show();
                _dialog.Dismiss();
            } else {
                Toast.MakeText(v.Context, "Cant update password!", ToastLength.Short).Show();
                Show();
            }
        }
    }
    public void OnDismiss (IDialogInterface dialog)
    {
        if (!(txtChangePassword.Text.Equals (txtChangePassword.Text))) {
            Show ();
        } else {
            _dialog.Dismiss();
        }
    }
    public void Show ()
    {
        _dialog.Show ();
    }
}

BTW,我使用Mono for Android而不是Eclipse。

答案 4 :(得分:0)

您可能需要定义自己的布局而不使用“官方”按钮;你要求的行为不是典型的对话。

答案 5 :(得分:0)

您可以从方法“show()”alertBuidler返回对话框。

AlertDialog.Builder adb = new AlertDialog.Builder(YourActivity.this);
//...code to add methods setPositive an setNegative buttons

调用“adb”的“show()”方法并获取Dialog

final AlertDialog dialog = adb.show();

因此,您可以在活动的任何代码点调用对话框中的任何按钮:

dialog.getButton(DialogInterface.BUTTON_POSITIVE).performClick();//or
dialog.getButton(DialogInterface.BUTTON_NEGATIVE).performClick();//or
dialog.getButton(DialogInterface.BUTTON_NEUTRAL).performClick();

答案 6 :(得分:0)

您无需创建自定义类。您可以为AlertDialog注册View.OnClickListener。此侦听器不会关闭AlertDialog。这里的诀窍是你需要在显示对话框后注册监听器,但它可以在OnShowListener中完成。您可以使用附件布尔变量来检查是否已经完成此操作,以便只执行一次:

/*
 * Prepare the alert with a Builder.
 */
AlertDialog.Builder b = new AlertDialog.Builder(this);

b.setNegativeButton("Button", new DialogInterface.OnClickListener() {
    @Override
    public void onClick(DialogInterface dialog, int which) {}
});
this.alert = b.create();

/*
 * Add an OnShowListener to change the OnClickListener on the
 * first time the alert is shown. Calling getButton() before
 * the alert is shown will return null. Then use a regular
 * View.OnClickListener for the button, which will not 
 * dismiss the AlertDialog after it has been called.
 */

this.alertReady = false;
alert.setOnShowListener(new DialogInterface.OnShowListener() {
    @Override
    public void onShow(DialogInterface dialog) {
        if (alertReady == false) {
            Button button = alert.getButton(DialogInterface.BUTTON_NEGATIVE);
            button.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    //do something
                }
            });
            alertReady = true;
        }
    }
});