Criando caixas de diálogo no Android (Dialogs)

(Last Updated On: 7 de dezembro de 2016)

No post onde vimos como criar context menu, criamos um menu de deletar um curso da lista, ou melhor, um item da lista. Para isso criamos o método deletar() que recebe a posição do curso, e então, deleta o curso a partir da posição:

private void deletar(int position) {
    listaDeCursos.remove(position);
    adapter.notifyDataSetChanged();
}

A princípio, esse método está perfeito, porém, uma funcionalidade de deletar é algo perigoso, pois o usuário, de fato, perde a informação! Portanto, a boa prática é fazer com que o usuário tenha ciência do que está preste a fazer.

Em outras palavras, precisamos, de alguma forma, alertar o usuário que a sua ação é perigosa! Como podemos chamar a atenção do usuário? Podemos tentar adicionar uma janela de confirmação. Algo próximo do exemplo a baixo:

alert_dialog

No Android, essas caixinhas são chamadas de caixas de diálogo, ou tecnicamente, Dialogs. Então como podemos adicionar um dialog antes que o curso seja deletado? Instânciando a classe Dialog?

Parece óbvio, certo? Porém, o próprio Google informa que a Dialog é uma classe base, e que devemos evitar sua instância! Em outras palavras, a sugestão do Google é que usemos suas subclasses, isto é, classes mais específicas!

Dentre as suas subclasses, temos a AlertDialog que nos permite criar dialogs de alerta! Então vamos instânciá-la!

private void deletar(int position) {

    new AlertDialog();
    adapter.notifyDataSetChanged();
    listaDeCursos.remove(position);

}

Opa! erro de compilação? Por que será? A classe AlertDialog, por padrão, não permite que classes de diferentes pacotes consigam instânciá-la, porém, ela nos disponibiliza a classe estática e interna Builder que recebe um Context como parâmetro. Já que estamos em uma Activity, podemos enviar o this:

new AlertDialog.Builder(this);

Em outras palavras, quando utilizamos a AlertDialog dentro das nossas classes, sempre faremos a instância da classe AlertDialog.Builder.

Agora que temos uma instância, o que faremos? Podemos utilizar os diversos métodos que essa classe nos fornece, começaremos pelo setTitle() que nos permite adicionar um título ao dialog:

new AlertDialog.Builder(this).setTitle("Deletando curso")

Mas o nosso dialog tem apenas um título? Ele também precisa de uma mensagem, certo? Porém, não referenciamos essa instância para um objeto, então como podemos adicionar uma mensagem?

O legal dos métodos do AlertDialog.Builder é que eles devolvem o próprio objeto, ou seja, podemos chamar mais de um método ao mesmo tempo. Portanto, vamos também chamar o método setMessage():

new AlertDialog.Builder(this).setTitle("Deletando curso").
    setMessage("Tem certeza que deseja deletar esse curso?")

Agora que o nosso dialog tem um título e mensagem, basta apenas exibí-lo! Para isso, finalizamos as chamadas de métodos com o método show():

private void deletar(int position) {

    new AlertDialog.Builder(this).setTitle("Deletando curso").
        setMessage("Tem certeza que deseja deletar esse curso?").show()
    adapter.notifyDataSetChanged();
    listaDeCursos.remove(position);

}

Vamos rodar a nossa App e verificar o resultado:

deletando_com_alert_sem_confirmacao

Está faltando um botão de confirmação! E calma aí… Ele apagou o curso também! Veja que temos 2 problemas:

  • Adicionar algum botão de confirmação.
  • Excluir o curso apenas se clicar no botão de confirmação.

Para adicionarmos um botão nesse dialog, basta apenas chamarmos o método setPositiveButton():

new AlertDialog.Builder(this).setTitle("Deletando curso").
    setMessage("Tem certeza que deseja deletar esse curso?")
    .setPositiveButton()
    .show();

Porém, precisamos enviar 2 parâmetros:

  • 1º parâmetro: texto que será exibido para esse botão.
  • 2º parâmetro: ação após tocá-lo.

Então daremos o nome para esse botão de “sim”:

new AlertDialog.Builder(this).setTitle("Deletando curso").
    setMessage("Tem certeza que deseja deletar esse curso?")
    .setPositiveButton("sim")
    .show();

Para adicionarmos uma ação, precisamos implementar a interface DialogInterface.OnClickListener, faremos isso da mesma forma como costumamos ver nos outros listener do Android, ou seja, pelo recurso de classe anônima:

new AlertDialog.Builder(this)
    .setTitle("Deletando curso")
    .setMessage("Tem certeza que deseja deletar esse curso?")
    .setPositiveButton("sim", 
        new DialogInterface.OnClickListener() {
        @Override
        public void onClick(DialogInterface dialogInterface, int i) {
                
        }
    })
    .show();

Quando o usuário tocar no “sim”, o que deve acontecer? deletar o curso né? Portanto, adicionaremos o código que deleta o curso dentro do onClick()

private void deletar(int position) {
    new AlertDialog.Builder(this).setTitle("Deletando curso")
        .setMessage("Tem certeza que deseja deletar esse curso?")
        .setPositiveButton("sim", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialogInterface, int i) {
                adapter.notifyDataSetChanged();
                listaDeCursos.remove(position);
            }
        })
        .show();
}

Outro erro de compilação!? Agora na linha listaDeCursos.remove(position); Por que será? 🙁

Já que a variável position está fora do escopo da implementação do DialogInterface.OnClickListener(), precisamos deixá-la como final, ou seja, basta apenas modificarmos no parâmetro do método deletar():

private void deletar(final int position) {
    //restante do código
}

Já podemos testar, porém, antes de executar a nossa App, precisamos pensar na seguinte questão:

  • E se o usuário não querer deletar?

E então? Como o usuário faz pra não deletar sem tocar no botão “back” do Android? Por enquanto não demos essa opção pra ele. Então vamos adicionar também esse botão!

Da mesma forma que existe o método setPositiveButton(), também existe o seu oposto, ou seja, o setNegativeButton() que recebe os mesmos parâmetros do setPositiveButton(). Então vamos utilizá-lo enviando o primeiro parâmetro com o valor “não”:

new AlertDialog.Builder(this)
    .setTitle("Deletando curso")
    .setMessage("Tem certeza que deseja deletar esse curso?")
    .setPositiveButton("sim", 
        new DialogInterface.OnClickListener() {
        @Override
        public void onClick(DialogInterface dialogInterface, int i) {
						adapter.notifyDataSetChanged();
            listaDeCursos.remove(position);
        }
    })
    .setNegativeButton("não")
    .show();

Porém, lembra que também precisamos adicionar uma ação para o botão? Pois é, qual ação daremos para ele? A princípio, nenhuma, mas como informamos isso? Simples! basta apenas enviar um null:

new AlertDialog.Builder(this)
    .setTitle("Deletando curso")
    .setMessage("Tem certeza que deseja deletar esse curso?")
    .setPositiveButton("sim", 
        new DialogInterface.OnClickListener() {
        @Override
        public void onClick(DialogInterface dialogInterface, int i) {
						adapter.notifyDataSetChanged();
						listaDeCursos.remove(position);
        }
    })
    .setNegativeButton("não", null)
    .show();

Rodando a nossa App novamente, temos o seguinte resultado:

mostrando_opcoes_do_alertdialog

Veja que agora alertamos o usuário e ainda mostramos quais opções ele pode escolher, isto é, se ele quer confirmar ou cancelar a determinada ação!

Nesse post vimos como podemos interagir com o usuário a partir de um dialog. A partir do dialog, podemos mostrar tipo de mensagem de alerta que permite que o usuário confirme ou não alguma ação que está acontecendo.

O que achou do dialog do Android? Muito bacana né? Deixe o seu comentário sobre essa ou outras implementações de dialog que conhece. 🙂

Que tal aprender a desenvolver para Android hoje mesmo? Na Alura, temos diversos cursos online de Android muito práticos, onde você aprende desde os conceitos mais básicos aos avançados.

FIQUE POR DENTRO

Content Editor at Alura and Software Developer

Próximo Artigo4 designers famosos que tiveram sucesso no mercado de tecnologia