Android – Como não fechar um AlertDialog quando um botão for selecionado. (How to prevent a dialog from closing when a button is clicked)


AlertDialog

 

No Android quando criamos um AlertDialog e definimos os botões, Possitive Button ou Negative Button, por padrão ao clicar neles a caixa de dialogo automaticamente é fechada, porem nem sempre queremos esta ação, as vezes queremos validar um EditText ou algo naquele dialogo, para não realizar duas interações como fechar o dialogo e abrir um outro informando o erro, vamos precisar cancelar a ação e inclui-la no momento desejado. Veremos abaixo como cancelar o evento que fecha o AlertDialog quando um botão é selecionado.

Abaixo é mostrado o código de exemplo, Exemplificando, devemos primeiramente passar null para o listener padrão do setPositiveButton ou setNegativeButton, para seu evento padrão não realizar o dismiss no dialog quando não querermos, o próximo passo é implementar o evento setOnShowListener do AlertDialog para quando o mesmo for carregado, vamos pegar o botão do AlertDialog e implementar um onClickListener diretamente ao botão (não da para fazer isso antes do .show(), até da para não utilizar o listener, mas assim já fica padronizado.), assim você consegue controlar quando e aonde realizar o dismiss no alertDialog, veja o código comentado:

import android.content.DialogInterface.OnShowListener;
import android.view.View.OnClickListener;

//Definimos o onShowListener para cancelar a ação.
//Definimos o OnClickListener para tratar o botão clicado.
public class MainActivity extends Activity implements 
OnShowListener, OnClickListener{

private AlertDialog dialog;

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

    //Criação do dialog builder
    AlertDialog.Builder builder = new AlertDialog.Builder(this);
    View view = LayoutInflater.from(this).inflate(R.layout.alert_dialog, null);
    builder.setView(view);

    //Importante passar NULL no setPositive e Negative Button
    //para que não utilize o listener padrão.
    builder.setPositiveButton(R.string.alerta_bt_ok, null);
    builder.setNegativeButton(R.string.alerta_bt_cancel, null);
    
    //Criamos a caixa de dialog e definimos a interface onShowListener
    dialog = builder.create();
    dialog.setOnShowListener(this);
    dialog.show();
}

//Metodo da interface onShowListener
@Override
public void onShow(DialogInterface d) {
   //Abaixo pegamos o botão do dialog, definimos um ID para ele
   //e definimos o OnClickListener para sermos notificado.
   Button b = dialog.getButton(DialogInterface.BUTTON_POSITIVE);
   b.setId(DialogInterface.BUTTON_POSITIVE);
   b.setOnClickListener(this);
}

//Metodo da interface onClickListener
@Override
public void onClick(View v) {
   //Verificamos se é o botão.
   //Aqui é aonde deve ser feita verificação necessária.
   if(v.getId()==DialogInterface.BUTTON_POSITIVE){
     //Este é o evento responsável por fechar o dialog.
     dialog.dismiss();
   }
}
}

Abaixo segue um código com um exemplo de tratamento de um editText dentro do dialog, não permitindo que ao clicar no botão e se o edit estiver vazio o mesmo continue.
Não é do meu costume implementar um AlertDialog customizado diretamente na Activity como fiz acima, porem é mais simples para explicação e entendimento. Normalmente eu crio uma classe estendendo o Builder do AlertDialog e utilizo um Callback para meu retorno e para deixar o código mais organizado. Veja a seguir:

import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnShowListener;
import android.view.View.OnClickListener;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;

public class AlertDialogGetPlaca extends AlertDialog.Builder implements
		OnShowListener, OnClickListener {
	public interface CallbackDialogGetPlaca {
		public void definePlaca(String placa);
	}

	private CallbackDialogGetPlaca callbackDialogGetPlaca;
	private AlertDialog dialog;
	private EditText placa;

	public AlertDialogGetPlaca(Context context,
			CallbackDialogGetPlaca callbackDialogGetPlaca) {
		super(context);
		this.callbackDialogGetPlaca = callbackDialogGetPlaca;
		setTitle(R.string.app_name);

		View view = LayoutInflater.from(context).inflate(R.layout.alert_dialog_getplaca, null);
		placa = (EditText)view.findViewById(R.id.getplaca_placa);
		setView(view);

		setPositiveButton(R.string.alerta_bt_iniciar_viagem, null);
		setNegativeButton(R.string.alerta_bt_voltar, null);
	}

   @Override
    public AlertDialog show() {
        dialog = create();
        dialog.setOnShowListener(this);
        dialog.show();
        return dialog;
    }

	@Override
	public void onShow(DialogInterface d) {
		Button b = dialog.getButton(DialogInterface.BUTTON_POSITIVE);
		b.setId(DialogInterface.BUTTON_POSITIVE);
		b.setOnClickListener(this);
	}

	@Override
	public void onClick(View v) {
		if(placa.getText().toString().trim().length()==0){
			placa.setError(getContext().getString(R.string.alert_placa_error));
		}else{
			if(callbackDialogGetPlaca!=null){
				callbackDialogGetPlaca.definePlaca(placa.getText().toString());
			}
			dialog.dismiss();
		}
	}

}

Sendo assim para utiliza-la basta estanciá-la e dar um .show();

Help DEV – Analista desenvolvedor Java / Android

http://helpdev.com.br/zarelli

2 thoughts on “Android – Como não fechar um AlertDialog quando um botão for selecionado. (How to prevent a dialog from closing when a button is clicked)

  1. Otimo, muito bom mesmo.

    Como eu faço pra adicionar o setNeutralButton e no onClick testar se é Neutral, Positive ou Negative?
    para que cada um tenha uma ação diferente.

    • Tudo bem Wesley,
      Voce adiciona da mesma maneira que adicionei o positive no exemplo e para diferenciar é utilizado o getId() no onclick() no caso aonde faz:

      if(v.getId()==DialogInterface.BUTTON_POSITIVE){
      //Este é o evento responsável por fechar o dialog.
      dialog.dismiss();
      }

      é só adicionar um else if com o negative ou neutral.

      EXEMPLO:

      public void onClick(View v) {
      //Verificamos se é o botão.
      //Aqui é aonde deve ser feita verificação necessária.
      if(v.getId()==DialogInterface.BUTTON_POSITIVE){
      //Este é o evento responsável por fechar o dialog.
      dialog.dismiss();
      }else if(v.getId()==DialogInterface.BUTTON_NEGATIVE){
      }
      }

      No metodo onShow voce tambem tem que lembrar de adiciona-los:

      @Override
      public void onShow(DialogInterface d) {
      //Abaixo pegamos o botão do dialog, definimos um ID para ele
      //e definimos o OnClickListener para sermos notificado.
      Button b = dialog.getButton(DialogInterface.BUTTON_POSITIVE);
      b.setId(DialogInterface.BUTTON_POSITIVE);
      b.setOnClickListener(this);

      Button b = dialog.getButton(DialogInterface.BUTTON_NEGATIVE);
      b.setId(DialogInterface.BUTTON_NEGATIVE);
      b.setOnClickListener(this);
      }

Deixe uma resposta

O seu endereço de email não será publicado Campos obrigatórios são marcados *

Você pode usar estas tags e atributos de HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>