2011-05-26 15 views
59

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

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

Pregunta similar: http://stackoverflow.com/questions/2620444/android-how-to -prevent-dialog-closed-or-remain-dialog-when-button-is-clicked –

+0

en la pantalla de inicio de sesión después de enviar los datos de inicio de sesión basados ​​en la respuesta, mostrando alerta con una vez más el nombre de usuario para confirmar y aceptar y cancelar los botones de la interfaz de diálogo. si el usuario no ingresa nada en el cuadro de diálogo y hace clic en ok, la ventana de diálogo se descarta, incluso no es para escribir. Una vez que haya verificado la validación, vacíela o no. Solo descarte si no está vacía. Otra pantalla muestra el error en edittext. Ayúdenme a hacerlo en diferentes formas desde el último día en adelante – Harsha

+1

Sería mejor [desactive el botón hasta que el usuario esté listo para continuar] (http://stackoverflow.com/a/40669929/3681880) en lugar de evitar que el diálogo se cierre después de que el usuario ya haya hecho clic en el botón. – Suragch

Respuesta

88

Sí, puedes. Es, básicamente, tiene que:

  1. creado el diálogo con DialogBuilder
  2. show() del cuadro de diálogo
  3. localizar los botones en el cuadro de diálogo se muestra y anulan su onClickListener

Por lo tanto, crear una clase de escucha:

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

Then w gallina que muestran el uso de diálogo:

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

Recuerde, es necesario mostrar el diálogo de lo contrario el botón no estará localizable. Además, asegúrese de cambiar DialogInterface.BUTTON_POSITIVE por el valor que haya utilizado para agregar el botón. También tenga en cuenta que al agregar los botones en DialogBuilder, deberá proporcionar onClickListeners; sin embargo, no puede agregar el oyente personalizado, el cuadro de diálogo se cerrará si no anula los oyentes después de llamar al show().

+0

¿Por qué crearía un oyente personalizado si ya está allí? Solo tiene que hacer lo que quiera donde ese "dialog.cancel();" es. – DallaRosa

+1

@DallaRosa analice la implementación de AlertController. @Sebastian Esto es lo mismo que yo y puedo confirmar que la respuesta de Kamen funciona. – pawelzieba

+0

Gracias por la buena muestra pero el tipo de variable "diálogo de diálogo final privado" debe ser AlertDialog en lugar de Diálogo, también el parámetro del método constrictor también debe ser AlertDialog. –

0

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

2

Así es como logro crear una ventana emergente persistente al cambiar 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, yo uso Mono para Android no Eclipse.

13

Creo que la respuesta es correcta por @Kamen, aquí es un ejemplo del mismo enfoque utilizando una clase anónima en lugar de por lo que es todo en una corriente 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. 
      } 
     }); 

me escribió una escritura más detallada hasta 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.

26

Gracias 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) a 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. 
       } 
      }); 
+0

Esto hubiera sido mucho más útil como comentario o edición en mi respuesta ... pero supongo que hice lo mismo con mi respuesta frente a la solución orignal @Kamen, entonces c'est la vie. – Sogger

+0

@Sogger Perdón, no quería hacerte daño, pero era más nuevo en stackoverflow en ese momento. Pero, como dije al inicio de la respuesta, esta respuesta está dedicada a ti. Désolé. – Shailesh

0

Puede obtener el diálogo regresó del método "show()" alertBuidler.

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

llamada el "show()" método de "adb" y obtener de diálogo

final AlertDialog dialog = adb.show(); 

para que pueda llamar cualquier botón de su diálogo en cualquier punto del código en su actividad:

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

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 utilizar una variable booleana accesorio para comprobar si esto ya se ha hecho de forma que sólo se realiza 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; 
     } 
    } 
}); 
Cuestiones relacionadas