Come visualizzare una finestra di dialogo Sì / No su Android?


358

Sì, so che c'è AlertDialog.Builder, ma sono scioccato nel sapere quanto sia difficile (beh, almeno non adatto ai programmatori) visualizzare una finestra di dialogo in Android.

Ero uno sviluppatore .NET e mi chiedo se esiste un equivalente di Android tra i seguenti?

if (MessageBox.Show("Sure?", "", MessageBoxButtons.YesNo) == DialogResult.Yes){
    // Do something...
}


3
Come posso ripristinare il codice AlertDialog e gestire gli eventi (sì, nessuna azione) in tutte le schermate? In .Net usiamo la classe Action per gestire gli eventi, c'è un modo per implementarlo? So che usando le interfacce possiamo farlo ma in qualche modo alternativo?
Ravikumar11,

2
Sì .... noi sviluppatori .NET abbiamo davvero dei problemi con Android .... Mi chiedo se Xamarin sia un ottimo strumento?
Daniel Möller,

Risposte:


745

AlertDialog.Builder non è poi così difficile da usare. All'inizio è un po 'intimidatorio, ma una volta che lo hai usato è sia semplice che potente. So che hai detto che sai come usarlo, ma ecco comunque solo un semplice esempio:

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

Puoi anche riutilizzarlo DialogInterface.OnClickListenerse ne hai altri caselle sì / no che dovrebbero fare la stessa cosa.

Se stai creando la finestra di dialogo all'interno di a View.OnClickListener, puoi utilizzare view.getContext()per ottenere il contesto. In alternativa puoi usare yourFragmentName.getActivity().


3
nuovo AlertDialog.Builder (questo); Errore di compilazione: "Il costruttore AlertDialog.Builder (nuovo View.OnClickListener () {}) non è definito"
Eric Leschinski,

3
La finestra di dialogo semplice e utile, tra l'altro, si chiuderà automaticamente dopo che l'utente avrà fatto clic sul pulsante "SÌ" o "NO". Non c'è niente che tu debba fare.
RRTW

9
Io stesso, l'ho usato molte volte. Ma ho scoperto che in realtà è più facile e veloce cercare su SO. L'esempio di codice fornito qui è così semplice ... Vorrei davvero che la documentazione di Android fosse simile a questa.
Radu,

4
@EricLeschinski probabilmente "questo" non è un contesto, prova questo: AlertDialog.Builder builder = new AlertDialog.Builder(getView().getContext());
cldrr

1
@davidglorioso L'ordine di sì / no o no / sì dipende dalla versione di Android e non puoi controllarlo. Non ricordo quando è cambiato, ma penso che fosse in 4.xo 5. Detto questo, non dovresti cambiarlo comunque. Tutte le app che utilizzano finestre di dialogo di avviso standard useranno lo stesso ordine di pulsanti no / sì e sarebbe confuso per gli utenti se le tue fossero diverse. Se vuoi davvero che sia diverso, dovrai impostare manualmente i pulsanti positivi / negativi in ​​base alla versione di Android.
Steve Haley,

163

Prova questo:

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

25
Personalmente, mi piace quel frammento di codice più della risposta accettata
John,

1
@nikki perché entrambi hanno dismiss ()?
Likejudo,

The constructor AlertDialog.Builder(MainActivity.DrawerItemClickListener) is undefined
Hash,

@likejiujitsu è perché vuoi pulire il dialogo dalla memoria in ogni caso dopo aver fatto il tuo lavoro.
Avi Levin,

32

La risposta di Steve H è precisa, ma ecco un po 'più di informazioni: la ragione per cui le finestre di dialogo funzionano nel modo in cui funzionano è perché le finestre di dialogo in Android sono asincrone (l'esecuzione non si interrompe quando viene visualizzata la finestra di dialogo). Per questo motivo, è necessario utilizzare un callback per gestire la selezione dell'utente.

Dai un'occhiata a questa domanda per una discussione più lunga tra le differenze in Android e .NET (in relazione alle finestre di dialogo): Dialogs / AlertDialogs: Come "bloccare l'esecuzione" mentre la finestra di dialogo è attiva (in stile .NET)


8
Grazie, il fatto che i dialoghi Android siano asincroni rende tutto chiaro (e ragionevole) ora. Sembra che abbia bisogno di "pensare a .Net" durante lo sviluppo di app per Android :)
Solo il

Cordiali saluti: ciò che chiamate "finestra di dialogo asincrona" è chiamato "finestra di dialogo non modale" nella terminologia della GUI, mentre "finestra di dialogo sincrona" è chiamata "finestra di dialogo modale". Android non dispone di finestre di dialogo modali (tranne in casi molto eccezionali).
Alex,

Android non consente le finestre di dialogo modali di sistema per un motivo molto valido: non è consentito interferire con altre app sul dispositivo.
Renascienza,

14

Questo funziona per me:

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

7

Chiedere a una persona se desidera chiamare o meno la finestra di dialogo.

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

5

La risposta di Steves è corretta anche se obsoleta con frammenti. Ecco un esempio con FragmentDialog.

La classe:

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

Per avviare la finestra di dialogo:

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

Puoi anche consentire alla classe di implementarlo onClickListenere utilizzarlo al posto dei listener incorporati.


@likejiujitsu sopra è sufficiente.
Warpzit,

Creare una classe FragmentDialog solo per fare una casella no / yes è un po 'di overdesign ... :) Un AlertDialog predefinito è abbastanza giusto, ancora.
Renascienza,

@Renascienza si ma credo sia obsoleto.
Warpzit,

Non proprio. FragmentDialog è stato aggiunto come utile per consentire di riutilizzare un frammento in una finestra di dialogo. Frammenti riguarda il riutilizzo dell'interfaccia utente. Poiché non è necessario utilizzare i frammenti solo perché è una novità (i frammenti non vengono per sostituire le attività), non è necessario utilizzare FragmentDialog nei casi in cui non è necessario alcun guadagno. Semplici allarmi Sì / No, ad esempio.
Renascienza,

2
La mia raccomandazione è: se hai bisogno di riutilizzare non solo un layout, ma il codice di sfondo e del ciclo di vita, usa una finestra di dialogo Frammento. Con il frammento hai il controllo del ciclo di vita delle attività correlate e puoi reagire a eventi come creare (poiché l'interfaccia utente viene ricreata quando l'utente ruota il suo dispositivo), mettere in pausa, riprendere, ecc. In breve, una finestra di dialogo con un'interfaccia utente elaborata. Se non ti serve e la tua finestra di dialogo è piuttosto semplice, le normali finestre di dialogo funzionano bene.
Renascienza,

5

Grazie Nikki la tua risposta mi ha aiutato a migliorare un esistente semplicemente aggiungendo la mia azione desiderata come segue

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

Ho avuto l'impressione che l'OP non volesse usare AlertDialog.Builder. OP vuole sapere se esiste un metodo di utilità di scelta rapida,
walrii

1
Ho scritto lo stesso codice ma prima appare NO e poi SÌ sostanzialmente è una finestra di dialogo NO / SÌ ma ho bisogno di una finestra di dialogo SÌ / NO Come
posso

Per quanto riguarda SÌ / NO vs NO / SÌ, vedere questa risposta: stackoverflow.com/a/13644589/1815624 è possibile manipolarlo come descritto in questa risposta: stackoverflow.com/a/13644536/1815624
CrandellWS

4

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

3

Mostra la finestra di dialogo in modo anonimo come catena di comandi e senza definire un altro oggetto:

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

2

Tutte le risposte qui si riducono a un codice lungo e non di facile lettura: proprio quello che la persona che chiedeva stava cercando di evitare. Per me, l'approccio più semplice è quello di impiegare lambda qui:

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 su Android richiede il plug-in retrolambda ( https://github.com/evant/gradle-retrolambda ), ma è estremamente utile per scrivere codice più pulito comunque.


1

Grazie. Uso l'API Level 2 (Android 1.1) e invece di BUTTON_POSITIVEe BUTTON_NEGATIVEdevo usare BUTTON1e BUTTON2.


1

1.Crea avviso Impostare il messaggio di dialogo, titolo e pulsante positivo, negativo:

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. Ora trova entrambi i pulsanti in DialogInterface Fai clic su quindi setOnClickListener ():

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. Per mostrare il registro degli avvisi:

alertDialog.show();

Nota: non dimenticare la parola chiave finale con AlertDialog.


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

0

puoi implementare una soluzione generica per le decisioni e utilizzare in un altro caso non solo per sì / no e personalizzare l'avviso con animazioni o layout:

Qualcosa come questo; prima crea la tua classe per i dati di trasferimento:

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

dopo un'interfaccia per restituire il risultato

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

Ora puoi creare facilmente un util per l'accesso (in questa classe puoi implementare diverse animazioni o layout personalizzati per l'avviso):

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

e l'ultima chiamata in attività o frammento; puoi usarlo nel tuo caso o per altre attività:

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

0

Puoi farlo così facilmente in Kotlin:

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

0

Per Kotlin in 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()
    } 

0

Implementazione di Kotlin.

Puoi creare una semplice funzione come questa:

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

e chiamalo così:

dialogYesOrNo(
  this,
  "Question",
  "Would you like to eat?",
  DialogInterface.OnClickListener { dialog, id ->
    // do whatever you need to do when user presses "Yes"
  }
})
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.