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