Como exibir uma caixa de diálogo Sim / Não no Android?

358

Sim, eu sei que existe o AlertDialog.Builder, mas estou chocado ao saber o quão difícil (pelo menos não é favorável ao programador) exibir uma caixa de diálogo no Android.

Eu costumava ser um desenvolvedor .NET e gostaria de saber se existe algum equivalente Android do seguinte?

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

fonte
3
Como faço para reemitir o código AlertDialog e manipular eventos (sim, nenhuma ação) em todas as telas? No .Net, usamos a classe Action para manipular os eventos. Existe alguma maneira de implementar isso? Eu sei que usando interfaces, podemos fazer isso, mas de qualquer maneira alternativa?
precisa saber é o seguinte
2
Sim .... nós, desenvolvedores .NET, realmente temos dificuldade com o Android ... Será que o Xamarin é uma ótima ferramenta?
Daniel Möller

Respostas:

745

AlertDialog.Builder realmente não é tão difícil de usar. É um pouco intimidador no começo, com certeza, mas depois de usá-lo um pouco, é simples e poderoso. Eu sei que você disse que sabe usá-lo, mas aqui está apenas um exemplo simples:

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

Você também pode reutilizar DialogInterface.OnClickListenerse houver outras caixas sim / não que devem fazer a mesma coisa.

Se você estiver criando o Diálogo a partir de a View.OnClickListener, poderá usar view.getContext()para obter o Contexto. Alternativamente, você pode usar yourFragmentName.getActivity().

Steve Haley
fonte
3
novo AlertDialog.Builder (isto); Erro em tempo de compilação: 'O construtor AlertDialog.Builder (novo View.OnClickListener () {}) está indefinido'
Eric Leschinski 04/04
3
O diálogo simples e útil, aliás, será descartado após o usuário clicar no botão "SIM" ou "NÃO". Não há nada que você precise fazer.
RRTW
9
Eu mesmo, já o usei muitas vezes. Mas descobri que é realmente mais fácil e rápido pesquisar no SO. O exemplo de código fornecido aqui é tão simples ... Eu realmente gostaria que a documentação do Android fosse assim.
Radu
4
@EricLeschinski provavelmente "isto" não é um contexto, tente este: AlertDialog.Builder builder = new AlertDialog.Builder(getView().getContext());
cldrr
11
@davidglorioso A ordem de sim / não ou não / sim depende da versão do Android e você não pode controlá-la. Não me lembro quando isso mudou, mas acho que estava no 4.x ou 5. Dizendo isso, você não deve mudar de qualquer maneira. Todos os aplicativos que usam caixas de diálogo de alerta padrão usam a mesma ordem de botão não / sim e seria confuso para os usuários se o seu fosse diferente. Se você realmente deseja que seja diferente, precisará definir manualmente seus botões positivo / negativo, dependendo da versão do Android.
Steve Haley
163

Tente o seguinte:

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
fonte
25
Pessoalmente, eu gosto disso trecho de código mais do que a resposta aceita
John
11
@nikki Por que os dois têm Disp ()?
likejudo 15/03
The constructor AlertDialog.Builder(MainActivity.DrawerItemClickListener) is undefined
hash de
@likejiujitsu é porque você deseja limpar a caixa de diálogo da memória em qualquer caso depois de fazer seu trabalho.
Avi Levin
32

A resposta de Steve H é imediata, mas eis um pouco mais de informação: a razão pela qual as caixas de diálogo funcionam da maneira como funcionam é porque as caixas de diálogo no Android são assíncronas (a execução não para quando a caixa de diálogo é exibida). Por esse motivo, é necessário usar um retorno de chamada para lidar com a seleção do usuário.

Confira esta pergunta para uma discussão mais longa entre as diferenças no Android e .NET (no que se refere às caixas de diálogo): Dialogs / AlertDialogs: Como "bloquear a execução" enquanto a caixa de diálogo está ativa (estilo .NET)

Erich Douglass
fonte
8
Obrigado, o fato de as caixas de diálogo do Android serem assíncronas deixa tudo claro (e razoável) agora. Parece que eu preciso "pensar fora da Net" ao desenvolver aplicativos para Android :)
Solo
FYI: o que você chama de "diálogo assíncrono" é chamado de "diálogo sem modelo" na terminologia da GUI, enquanto "diálogo síncrono" é chamado de "diálogo modal". O Android não apresenta diálogos modais (exceto em casos muito excepcionais).
22412 Alex
O Android não permite diálogos modais do sistema por um motivo muito bom: não é permitido interferir com outros aplicativos no dispositivo.
Renascienza
14

Isso está funcionando para mim:

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

Perguntar a uma pessoa se ele deseja ligar ou não para a caixa de 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
fonte
5

A resposta de Steves está correta, embora desatualizada com fragmentos. Aqui está um exemplo com FragmentDialog.

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

Para iniciar a caixa de diálogo:

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

Você também pode permitir que a classe implemente onClickListenere use isso em vez de ouvintes incorporados.

Warpzit
fonte
@likejiujitsu acima é suficiente.
Warpzit 16/03
Criar uma classe FragmentDialog apenas para fazer uma caixa de não / sim é um pouco de excesso de design ... :) Um AlertDialog padrão é justo o suficiente, ainda.
Renascienza
@Renascienza sim, mas acredito que seja obsoleto.
Warpzit
Na verdade não. FragmentDialog foi adicionado como uma coisa útil para permitir que você reutilize um fragmento em uma caixa de diálogo. Fragmentos é tudo sobre reutilização da interface do usuário. Como você não precisa usar fragmentos apenas porque é algo novo (os fragmentos não substituem as atividades), não é necessário usar o FragmentDialog nos casos em que não há ganho a fazer. Alertas Sim / Não simples, por exemplo.
Renascienza
2
Minha recomendação é: se você precisar reutilizar não apenas um layout, mas um código de plano de fundo e ciclo de vida, use uma caixa de diálogo Fragmento. Com o fragmento, você tem o controle do ciclo de vida da atividade relacionada e pode reagir a eventos como criar (como a interface do usuário é recriada quando o usuário gira o dispositivo), pausar, retomar etc. Em poucas palavras, um diálogo com uma interface do usuário elaborada. Se você não precisa disso e sua caixa de diálogo é bastante simples, as caixas de diálogo regulares funcionam bem.
Renascienza
5

Obrigado Nikki, sua resposta me ajudou a melhorar uma existente simplesmente adicionando a ação desejada da seguinte forma

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
fonte
Tive a impressão de que o OP não queria usar o AlertDialog.Builder. OP wats de saber se existe um método utilitário atalho,
walrii
11
Eu escrevi o mesmo código, mas NÃO aparece em primeiro lugar e depois SIM basicamente é um NO / YES caixa de diálogo, mas eu preciso de uma caixa de SIM / NÃO diálogo Como faço para fazê-lo
Sagar Devanga
Quanto ao SIM / NÃO vs NO / YES ver esta resposta: stackoverflow.com/a/13644589/1815624 você pode manipulá-lo como discribed nesta resposta: stackoverflow.com/a/13644536/1815624
CrandellWS
4

Em 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
fonte
3

Mostrar diálogo anonimamente como cadeia de comandos e sem definir outro 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
fonte
2

Todas as respostas aqui se resumem a códigos longos e não fáceis de ler: exatamente o que a pessoa que estava pedindo estava tentando evitar. Para mim, foi a abordagem mais fácil é empregar lambdas aqui:

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 no Android exigem o plug-in retrolambda ( https://github.com/evant/gradle-retrolambda ), mas é extremamente útil na redação de códigos mais limpos.

javaxian
fonte
1

Obrigado. Eu uso a API Nível 2 (Android 1.1) e, em vez de BUTTON_POSITIVEe BUTTON_NEGATIVEeu tenho que usar BUTTON1e BUTTON2.

cristão
fonte
1

1.Crie a mensagem, o título e o botão Positivo, Negativo do 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.Agora encontre os dois botões em DialogInterface Clique em 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.Para mostrar o diálogo de alerta:

alertDialog.show();

Nota: Não esqueça a palavra-chave final com AlertDialog.

Wajid khan
fonte
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
fonte
0

você pode implementar uma solução genérica para decisões e usar em outro caso, não apenas para sim / não e personalizar o alerta com animações ou layout:

Algo assim; primeiro crie sua classe para transferir dados:

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

depois de uma interface para retornar o 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);
}

Agora você pode criar utilitários para acessar facilmente (nesta classe, você pode implementar diferentes animações ou layouts personalizados para o 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();
    }
}

e a última chamada em atividade ou fragmento; você pode usar isso no seu caso ou em outra tarefa:

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
fonte
0

Você pode fazer isso tão facilmente no Kotlin:

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

Para Kotlin no 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
fonte
0

Implementação Kotlin.

Você pode criar uma função simples 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()
    }

e chame assim:

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