Diálogo Android, mantenga abierto el cuadro de diálogo cuando se presiona el botón

Me gustaría mantener mi cuadro de diálogo abierto cuando presiono un botón. Por el momento se está cerrando.

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(); 

Sí tu puedes. Básicamente necesitas:

  1. Crear el diálogo con DialogBuilder
  2. mostrar () el diálogo
  3. Encuentre los botones en el cuadro de diálogo que se muestra y anule su onClickListener

Entonces, crea una clase de oyentes:

 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(); } } 

Luego, al mostrar el diálogo, use:

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

Recuerde, debe mostrar el cuadro de diálogo, de lo contrario, el botón no se podrá encontrar. Además, asegúrese de cambiar DialogInterface.BUTTON_POSITIVE al valor que utilizó para agregar el botón. También tenga en cuenta que al agregar los botones en el DialogBuilder deberá proporcionar onClickListeners ; sin onClickListeners , no puede agregar el oyente personalizado allí; el diálogo aún se desactivará si no anula los oyentes después de llamar a show() .

Gracias a Sogger por su respuesta, pero hay un cambio que tenemos que hacer aquí, es decir, antes de crear el diálogo debemos establecer el botón positivo (y el botón negativo si es necesario) en AlertDialog de la manera tradicional, eso es todo.

Referenciado por Sogger.

Aquí está el ejemplo de muestra …

 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. } }); 

Creo que la respuesta de @Kamen es correcta, aquí hay un ejemplo del mismo enfoque que usa una clase anónima, de modo que todo está en una secuencia de código:

 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. } }); 

Escribí una escritura más detallada para responder la misma pregunta aquí https://stackoverflow.com/a/15619098/579234, que también tiene ejemplos para otros cuadros de diálogo como DialogFragment y DialogPreference.

Así es como logro crear una ventana emergente persistente cuando cambio la contraseña.

 // 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 (); } } 

Por cierto, uso Mono para Android, no Eclipse.

Probablemente necesites definir tu propio diseño y no usar los botones “oficiales”; el comportamiento que está solicitando no es típico de un diálogo.

Puede obtener el Diálogo devuelto por el método “show ()” alertBuidler.

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

Llame al método “show ()” de “adb” y obtenga el cuadro de diálogo

 final AlertDialog dialog = adb.show(); 

De modo que puede llamar a cualquier botón de su diálogo en cualquier punto del código de su actividad:

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

No necesita crear una clase personalizada. Puede registrar View.OnClickListener para AlertDialog. Este oyente no ignorará el AlertDialog. El truco aquí es que debe registrar el oyente después de que se haya mostrado el diálogo, pero se puede hacer claramente dentro de un OnShowListener. Puede usar una variable booleana accesoria para verificar si esto ya se ha hecho para que solo se haga una vez:

 /* * 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; } } });