
I was dealing with the case of use an EditText inside my AlertDialog that is created inside an DialogFragment last week and I remembered that I could write a tip about some problems of it. What problems? It’s simple…An EditText…inside an AlertDialog…Ok, but how to avoid the dismiss of the Dialog when the user click in a positive of negative button? Imagine that the user clicks on the positive button and, when your button’s listener checks the EditText value, it figures out that the value is invalid. Your code will warn the user that the value is invalid, but, your dialog suddently is dismissed even without you command it after the warn. Why?
Yes, positive and negative buttons will always dismiss the dialog, even without your order. How to avoid it? I’ve found a great answer on stackoverflow that will help us.
________________
What happens with AlertDialog’s setButton() method (and I imagine the same with AlertDialogBuilder’s setPositiveButton() and setNegativeButton()) is that the button you set (e.g. AlertDialog.BUTTON_POSITIVE) with it will actually trigger TWO different OnClickListener objects when pressed. The first being DialogInterface.OnClickListener, which is a parameter to setButton(), setPositiveButton(), and setNegativeButton(). The other is View.OnClickListener, which will be set to automatically dismiss your AlertDialog when any of its button is pressed – and is set by AlertDialog itself.
What you can do is to use setButton() with null as the DialogInterface.OnClickListener, to create the button, and then call your custom action method inside View.OnClickListener. For example,
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@Override | |
public Dialog onCreateDialog(Bundle savedInstanceState) { | |
AlertDialog alertDialog = new AlertDialog(getActivity()); | |
// set more items… | |
alertDialog.setButton(AlertDialog.BUTTON_POSITIVE, "OK", null); | |
return alertDialog; | |
} |
Then, you may override the default AlertDialog’s buttons’ View.OnClickListener (which would otherwise dismiss the dialog) in the DialogFragment’s onResume() method:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@Override | |
public void onResume() { | |
super.onResume(); | |
AlertDialog alertDialog = (AlertDialog) getDialog(); | |
Button okButton = alertDialog.getButton(AlertDialog.BUTTON_POSITIVE); | |
okButton.setOnClickListener(new View.OnClickListener() { | |
@Override | |
public void onClick(View v) { | |
// Do your stuff here | |
} | |
}); | |
} |
You will need to set this in the onResume() method because getButton() will return null until after the dialog has been shown! This should cause your custom action method to only be called once, and the dialog won’t be dismissed by default.