¿Cómo mostrar un cuadro de diálogo Sí / No en Android?

358

Sí, sé que hay AlertDialog.Builder, pero me sorprende saber cuán difícil (bueno, al menos no fácil de programar) para mostrar un diálogo en Android.

Solía ​​ser un desarrollador de .NET, y me pregunto si hay algún equivalente de Android de lo siguiente.

if (MessageBox.Show("Sure?", "", MessageBoxButtons.YesNo) == DialogResult.Yes){
    // Do something...
}
Solo
fuente
3
¿Cómo puedo recuperar el código de AlertDialog y manejar eventos (sí, sin acciones) en todas las pantallas? En .Net usamos la clase Action para manejar los eventos, ¿hay alguna forma de implementar esto? Sé que usando interfaces podemos hacer esto, ¿pero de alguna manera alternativa?
Ravikumar11
2
Sí ... nosotros, los desarrolladores de .NET, realmente lo pasamos mal con Android ... Me pregunto si Xamarin es una gran herramienta.
Daniel Möller

Respuestas:

745

AlertDialog.Builder realmente no es tan difícil de usar. Al principio es un poco intimidante, pero una vez que lo has usado un poco, es simple y poderoso. Sé que has dicho que sabes cómo usarlo, pero de todos modos aquí hay un simple ejemplo:

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

AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setMessage("Are you sure?").setPositiveButton("Yes", dialogClickListener)
    .setNegativeButton("No", dialogClickListener).show();

También puede reutilizar eso DialogInterface.OnClickListenersi tiene otros cuadros sí / no que deberían hacer lo mismo.

Si está creando el Diálogo desde dentro de a View.OnClickListener, puede usarlo view.getContext()para obtener el Contexto. Alternativamente puedes usar yourFragmentName.getActivity().

Steve Haley
fuente
3
nuevo AlertDialog.Builder (este); Error de tiempo de compilación: 'El constructor AlertDialog.Builder (nueva View.OnClickListener () {}) no está definido'
Eric Leschinski
3
El diálogo simple y útil, por cierto, se cerrará después de que el usuario haga clic en el botón "SÍ" o "NO". No hay nada que necesites hacer.
RRTW
99
Yo mismo, lo he usado muchas veces. Pero he descubierto que en realidad es más fácil y rápido buscarlo en SO. El ejemplo de código que se proporciona aquí es muy simple ... Realmente deseo que la documentación de Android se vea así.
Radu
44
@EricLeschinski probablemente "esto" no es un contexto, prueba este: AlertDialog.Builder builder = new AlertDialog.Builder(getView().getContext());
cldrr
1
@davidglorioso El orden de sí / no o no / sí depende de la versión de Android, y no puede controlarlo. No recuerdo cuándo cambió, pero creo que estaba en 4.xo 5. Cuando digo eso, no debería cambiarlo de todos modos. Todas las aplicaciones que usan diálogos de alerta estándar usarán el mismo orden de botones de no / sí, y sería confuso para los usuarios si los suyos fueran diferentes. Si realmente quieres que sea diferente, tendrás que configurar manualmente tus botones positivo / negativo dependiendo de la versión de Android.
Steve Haley
163

Prueba esto:

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

builder.setTitle("Confirm");
builder.setMessage("Are you sure?");

builder.setPositiveButton("YES", new DialogInterface.OnClickListener() {

    public void onClick(DialogInterface dialog, int which) {
        // Do nothing but close the dialog

        dialog.dismiss();
    }
});

builder.setNegativeButton("NO", new DialogInterface.OnClickListener() {

    @Override
    public void onClick(DialogInterface dialog, int which) {

        // Do nothing
        dialog.dismiss();
    }
});

AlertDialog alert = builder.create();
alert.show();
nikki
fuente
25
Personalmente, me gusta más ese fragmento de código que la respuesta aceptada
John
1
@nikki ¿por qué ambos tienen despedir ()?
likejudo
The constructor AlertDialog.Builder(MainActivity.DrawerItemClickListener) is undefined
hash
@likejiujitsu eso es porque quieres limpiar el diálogo de la memoria en cualquier caso después de hacer tu trabajo.
Avi Levin
32

La respuesta de Steve H es acertada, pero aquí hay un poco más de información: la razón por la que los diálogos funcionan de la manera en que lo hacen es porque los diálogos en Android son asíncronos (la ejecución no se detiene cuando se muestra el diálogo). Debido a esto, debe usar una devolución de llamada para manejar la selección del usuario.

Consulte esta pregunta para una discusión más larga entre las diferencias en Android y .NET (en lo que respecta a los diálogos): Diálogos / AlertDialogs: Cómo "bloquear la ejecución" mientras el diálogo está activo (estilo .NET)

Erich Douglass
fuente
8
Gracias, el hecho de que los cuadros de diálogo de Android son asíncronos hace que todo sea claro (y razonable) ahora. Parece que necesito "pensar en .Net" al desarrollar aplicaciones para Android :)
Solo
FYI: lo que llama "diálogo asincrónico" se llama "diálogo sin modo" en la terminología de la GUI, mientras que "diálogo sincrónico" se llama "diálogo modal". Android no presenta cuadros de diálogo modales (excepto en casos muy excepcionales).
Alex
Android no permite diálogos modales del sistema por una muy buena razón: no está permitido interferir con otras aplicaciones en el dispositivo.
Renascienza
14

Esto es trabajo para mí:

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

    builder.setTitle("Confirm");
    builder.setMessage("Are you sure?");

    builder.setPositiveButton("YES", new DialogInterface.OnClickListener() {

        public void onClick(DialogInterface dialog, int which) {

            // Do nothing, but close the dialog
            dialog.dismiss();
        }
    });

    builder.setNegativeButton("NO", new DialogInterface.OnClickListener() {

        @Override
        public void onClick(DialogInterface dialog, int which) {

            // Do nothing
            dialog.dismiss();
        }
    });

    AlertDialog alert = builder.create();
    alert.show();
picadillo
fuente
7

Preguntarle a una persona si quiere llamar o no a Diálogo.

import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ImageView;
import android.widget.Toast;

public class Firstclass extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {    
        super.onCreate(savedInstanceState);    
        setContentView(R.layout.first);

        ImageView imageViewCall = (ImageView) findViewById(R.id.ring_mig);

        imageViewCall.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v){
                try{
                    showDialog("0728570527");
                } catch (Exception e){
                    e.printStackTrace();
                }                   
            }    
        });    
    }

    public void showDialog(final String phone) throws Exception {
        AlertDialog.Builder builder = new AlertDialog.Builder(Firstclass.this);

        builder.setMessage("Ring: " + phone);       

        builder.setPositiveButton("Ring", new DialogInterface.OnClickListener(){
            @Override
            public void onClick(DialogInterface dialog, int which){

                Intent callIntent = new Intent(Intent.ACTION_DIAL);// (Intent.ACTION_CALL);                 
                callIntent.setData(Uri.parse("tel:" + phone));
                startActivity(callIntent);

                dialog.dismiss();
            }
        });

        builder.setNegativeButton("Abort", new DialogInterface.OnClickListener(){   
            @Override
            public void onClick(DialogInterface dialog, int which){
                dialog.dismiss();
            }
        });         
        builder.show();
    }    
}
Zar E Ahmer
fuente
5

La respuesta de Steves es correcta aunque anticuada con fragmentos. Aquí hay un ejemplo con FragmentDialog.

La clase:

public class SomeDialog extends DialogFragment {

    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        return new AlertDialog.Builder(getActivity())
            .setTitle("Title")
            .setMessage("Sure you wanna do this!")
            .setNegativeButton(android.R.string.no, new OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    // do nothing (will close dialog)
                }
            })
            .setPositiveButton(android.R.string.yes,  new OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    // do something
                }
            })
            .create();
    }
}

Para iniciar el diálogo:

            FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
            // Create and show the dialog.
            SomeDialog newFragment = new SomeDialog ();
            newFragment.show(ft, "dialog");

También puede dejar que la clase implemente onClickListenery use eso en lugar de oyentes integrados.

Warpzit
fuente
@likejiujitsu arriba es suficiente.
Warpzit
Crear una clase FragmentDialog solo para hacer un cuadro de no / sí es un poco de diseño excesivo ... :) Un AlertDialog predeterminado es bastante justo, todavía.
Renascienza
@Renascienza sí, pero creo que es obsoleto.
Warpzit
Realmente no. FragmentDialog se agregó como algo útil para permitirle reutilizar un fragmento en un cuadro de diálogo. Fragments tiene que ver con la reutilización de la interfaz de usuario. Como no necesita usar fragmentos solo porque es algo nuevo (los fragmentos no vienen a reemplazar las actividades), no necesita usar FragmentDialog en casos en los que no hay ganancia que hacer. Alertas simples de Sí / No, por ejemplo.
Renascienza
2
Mi recomendación es: si necesita reutilizar no solo un diseño, sino también un código de fondo y ciclo de vida, use un cuadro de diálogo Fragmento. Con el fragmento, tiene el control del ciclo de vida de la actividad relacionada y puede reaccionar a eventos como crear (ya que la interfaz de usuario se vuelve a crear cuando el usuario gira su dispositivo), pausar, reanudar, etc. En pocas palabras, un diálogo con alguna interfaz de usuario elaborada. Si no necesita esto y su diálogo es bastante simple, los diálogos regulares funcionan bien.
Renascienza
5

Gracias Nikki, tu respuesta me ha ayudado a mejorar una existente simplemente agregando mi acción deseada de la siguiente manera

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

builder.setTitle("Do this action");
builder.setMessage("do you want confirm this action?");

builder.setPositiveButton("YES", new DialogInterface.OnClickListener() {

    public void onClick(DialogInterface dialog, int which) {
        // Do do my action here

        dialog.dismiss();
    }

});

builder.setNegativeButton("NO", new DialogInterface.OnClickListener() {

    @Override
    public void onClick(DialogInterface dialog, int which) {
        // I do not need any action here you might
        dialog.dismiss();
    }
});

AlertDialog alert = builder.create();
alert.show();
CrandellWS
fuente
Me dio la impresión de que el OP no quería usar AlertDialog.Builder. OP quiere saber si hay un método de utilidad de acceso directo,
walrii
1
He escrito el mismo código pero NO aparece primero y luego SÍ básicamente es un cuadro de diálogo NO / SÍ pero necesito un cuadro de diálogo SÍ / NO ¿Cómo lo hago?
Sagar Devanga
En cuanto a YES / NO vs NO / YES, vea esta respuesta: stackoverflow.com/a/13644589/1815624 , puede manipularlo como se describe en esta respuesta: stackoverflow.com/a/13644536/1815624
CrandellWS
4

En Kotlin:

AlertDialog.Builder(this)
    .setTitle(R.string.question_title)
    .setMessage(R.string.question_message)
    .setPositiveButton(android.R.string.yes) { _, _ -> yesClicked() }
    .setNegativeButton(android.R.string.no) { _, _ -> noClicked() }
    .show()
Cristan
fuente
3

Mostrar el diálogo de forma anónima como cadena de comandos y sin definir otro objeto:

 new AlertDialog.Builder(this).setTitle("Confirm Delete?")
                        .setMessage("Are you sure?")
                        .setPositiveButton("YES",
                                new DialogInterface.OnClickListener() {
                                    public void onClick(DialogInterface dialog, int which) {

                                       // Perform Action & Dismiss dialog                                 
                                        dialog.dismiss();
                                    }
                                })
                        .setNegativeButton("NO", new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialog, int which) {
                                // Do nothing
                                dialog.dismiss();
                            }
                        })
                        .create()
                        .show();
Hitesh Sahu
fuente
2

Todas las respuestas aquí se reducen a un código extenso y no fácil de leer: justo lo que la persona que pregunta estaba tratando de evitar. Para mí, el enfoque más fácil es emplear lambdas aquí:

new AlertDialog.Builder(this)
        .setTitle("Are you sure?")
        .setMessage("If you go back you will loose any changes.")
        .setPositiveButton("Yes", (dialog, which) -> {
            doSomething();
            dialog.dismiss();
        })
        .setNegativeButton("No", (dialog, which) -> dialog.dismiss())
        .show();

Lambdas en Android requiere el complemento retrolambda ( https://github.com/evant/gradle-retrolambda ), pero de todos modos es muy útil para escribir código más limpio.

javaxian
fuente
1

Gracias. Uso el API Nivel 2 (Android 1.1) y en lugar de BUTTON_POSITIVEy BUTTON_NEGATIVEtengo que usar BUTTON1y BUTTON2.

cristiano
fuente
1

1.Cree el mensaje, el título y el botón Positivo, Negativo de AlertDialog:

final AlertDialog alertDialog = new AlertDialog.Builder(this)
                        .setCancelable(false)
                        .setTitle("Confirmation")
                        .setMessage("Do you want to remove this Picture?")
                        .setPositiveButton("Yes",null)
                        .setNegativeButton("No",null)
                        .create();

2.Ahora encuentre ambos botones en DialogInterface Haga clic y luego configureOnClickListener ():

alertDialog.setOnShowListener(new DialogInterface.OnShowListener() {
            @Override
            public void onShow(DialogInterface dialogInterface) {
                Button yesButton = (alertDialog).getButton(android.app.AlertDialog.BUTTON_POSITIVE);
                Button noButton = (alertDialog).getButton(android.app.AlertDialog.BUTTON_NEGATIVE);
                yesButton.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View view) {
                        //Now Background Class To Update Operator State
                        alertDialog.dismiss();
                        Toast.makeText(GroundEditActivity.this, "Click on Yes", Toast.LENGTH_SHORT).show();
                        //Do Something here 
                    }
                });

                noButton.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View view) {
                        alertDialog.dismiss();
                        Toast.makeText(GroundEditActivity.this, "Click on No", Toast.LENGTH_SHORT).show();
                        //Do Some Thing Here 
                    }
                });
            }
        });

3.Para mostrar el diálogo de alerta:

alertDialog.show();

Nota: No olvide la palabra clave final con AlertDialog.

Wajid khan
fuente
0
AlertDialog.Builder altBx = new AlertDialog.Builder(this);
    altBx.setTitle("My dialog box");
    altBx.setMessage("Welcome, Please Enter your name");
    altBx.setIcon(R.drawable.logo);

    altBx.setPositiveButton("Ok", new DialogInterface.OnClickListener()
    {
      public void onClick(DialogInterface dialog, int which)
      {
          if(edt.getText().toString().length()!=0)
          {
              // Show any message
          }
          else 
          {

          }
      }
    });
    altBx.setNeutralButton("Cancel", new DialogInterface.OnClickListener()
    {
      public void onClick(DialogInterface dialog, int which)
      {
          //show any message
      }

    });
  altBx.show();  
Singhak
fuente
0

puede implementar una solución genérica para decisiones y usarla en otro caso, no solo para sí / no, y personalizar la alerta con animaciones o diseño:

Algo como esto; Primero cree su clase para transferir datos:

public class AlertDecision {

    private String question = "";
    private String strNegative = "";
    private String strPositive = "";

    public AlertDecision question(@NonNull String question) {
        this.question = question;
        return this;
    }

    public AlertDecision ansPositive(@NonNull String strPositive) {
        this.strPositive = strPositive;
        return this;
    }

    public AlertDecision ansNegative(@NonNull String strNegative) {
        this.strNegative = strNegative;
        return this;
    }

    public String getQuestion() {
        return question;
    }

    public String getAnswerNegative() {
        return strNegative;
    }

    public String getAnswerPositive() {
        return strPositive;
    }
}

después de una interfaz para devolver el resultado

public interface OnAlertDecisionClickListener {

    /**
     * Interface definition for a callback to be invoked when a view is clicked.
     *
     * @param dialog the dialog that was clicked
     * @param object The object in the position of the view
     */
    void onPositiveDecisionClick(DialogInterface dialog, Object object);
    void onNegativeDecisionClick(DialogInterface dialog, Object object);
}

Ahora puede crear utilidades para acceder fácilmente (en esta clase puede implementar diferentes animaciones o diseños personalizados para la alerta):

public class AlertViewUtils {

    public static void showAlertDecision(Context context,
                                         @NonNull AlertDecision decision,
                                         final OnAlertDecisionClickListener listener,
                                         final Object object) {

        AlertDialog.Builder builder = new AlertDialog.Builder(context);
        builder.setMessage(decision.getQuestion());
        builder.setPositiveButton(decision.getAnswerPositive(),
                new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int which) {
                        listener.onPositiveDecisionClick(dialog, object);
                    }
                });

        builder.setNegativeButton(decision.getAnswerNegative(),
                new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int which) {
                        listener.onNegativeDecisionClick(dialog, object);
                    }
                });

        android.support.v7.app.AlertDialog dialog = builder.create();
        dialog.show();
    }
}

y la última llamada en actividad o fragmento; puede usar esto en su caso o para otra tarea:

public class MainActivity extends AppCompatActivity {

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity);
        initResources();
    }

    public void initResources() {
        Button doSomething = (Button) findViewById(R.id.btn);
        doSomething.setOnClickListener(getDecisionListener());
    }

    private View.OnClickListener getDecisionListener() {
        return new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                AlertDecision decision = new AlertDecision()
                        .question("question ...")
                        .ansNegative("negative action...")
                        .ansPositive("positive action... ");
                AlertViewUtils.showAlertDecision(MainActivity.this,
                        decision, getOnDecisionListener(), v);
            }
        };
    }

    private OnAlertDecisionClickListener getOnDecisionListener() {
        return new OnAlertDecisionClickListener() {
            @Override
            public void onPositiveDecisionClick(DialogInterface dialog, Object object) {

                //do something like create, show views, etc...
            }

            @Override
            public void onNegativeDecisionClick(DialogInterface dialog, Object object) {
                //do something like delete, close session, etc ...
            }
        };
    }
} 
Alex Zaraos
fuente
0

Puedes hacerlo tan fácil en Kotlin:

 alert("Testing alerts") {
    title = "Alert"
    yesButton { toast("Yess!!!") }
    noButton { }
}.show()
Serg Burlaka
fuente
0

Para Kotlin en Android ::

    override fun onBackPressed() {
        confirmToCancel()
    }

    private fun confirmToCancel() {
        AlertDialog.Builder(this)
            .setTitle("Title")
            .setMessage("Do you want to cancel?")
            .setCancelable(false)
            .setPositiveButton("Yes") {
                dialog: DialogInterface, _: Int ->
                dialog.dismiss()
                // for sending data to previous activity use
                // setResult(response code, data)
                finish()
            }
            .setNegativeButton("No") {
                dialog: DialogInterface, _: Int ->
                dialog.dismiss()
            }
            .show()
    } 
Partha Paul
fuente
0

Implementación de Kotlin.

Puede crear una función simple como esta:

fun dialogYesOrNo(
        activity: Activity,
        title: String,
        message: String,
        listener: DialogInterface.OnClickListener
    ) {
        val builder = AlertDialog.Builder(activity)
        builder.setPositiveButton("Yes", DialogInterface.OnClickListener { dialog, id ->
            dialog.dismiss()
            listener.onClick(dialog, id)
        })
        builder.setNegativeButton("No", null)
        val alert = builder.create()
        alert.setTitle(title)
        alert.setMessage(message)
        alert.show()
    }

y llámalo así:

dialogYesOrNo(
  this,
  "Question",
  "Would you like to eat?",
  DialogInterface.OnClickListener { dialog, id ->
    // do whatever you need to do when user presses "Yes"
  }
})
cristiano
fuente