Android: Prevent AlertDialog from closing when positive button is pressed

This is a tad tricky as it involves code to be called at specific times. To the user there isn't any difference, but the convenience of a good user experience is often overlooked.

private void dialogDeviceName() {
// Generate the dialog content
final LinearLayout layout = new LinearLayout(this);
LayoutInflater.from(this).inflate(R.layout.dialog_device_name, layout);

// Prefill the dialog content
EditText txt = (EditText) layout.findViewById(R.id.txtDeviceName);
txt.setText(G.SETTINGS.deviceName);

// Create the dialog (without showing)
final AlertDialog d = new AlertDialog.Builder(this)
// Shows the button, but assigns no event handler. This still closes by default
.setPositiveButton("Save", null)
.setNegativeButton("Cancel", null)
// Your other options here ...
.setView(layout)
.create();

// This is handy for re-adjusting the size of the dialog when a keyboard is shown
d.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);

// MUST call show before using AlertDialog.getButton(), otherwise you'll get null returned
d.show();

// Override the button's on-click so it doesn't close by default
d.getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
EditText txt = (EditText) layout.findViewById(R.id.txtDeviceName);
String newName = txt.getEditableText().toString().trim();

// This prevents the dialog from closing
if (newName.length() == 0) {
showToast("Please enter in a name for your broadcast.");
return;
}

// On success, the dialog must be closed manually
((TextView) findViewById(R.id.txtDeviceName)).setText(newName);
G.SETTINGS.deviceName = newName;
d.dismiss();
}
});
}

Now there are other solutions which only work on API level 8+, but this will compile and work on API level 3+ fine.

ylsb9gm
Stop diadogs from getting away, dead in their tracks (PS. It's sleeping)

Now the order for these key points are:

  • Create the dialog and specify that you want a positive button: setPositiveButton("Save", null)
  • Show the dialog so the buttons are created
  • Get the button and override it's onClick() handler with your own
  • Remember to dismiss the dialog on success

One of the tricky parts is AlertDialog.Builder.show() must be called prior to calling AlertDialog.getButton(). From the docs:

Returns: The button from the dialog, or null if a button does not exist.

Doesn't say anything about showing the dialog first. I guess it's just one of those undocumented quirks.

The rest of the sample code is specific to my Air Waves app, but you can read the code comments if there is any confusion.

Sources

 
Copyright © Twig's Tech Tips
Theme by BloggerThemes & TopWPThemes Sponsored by iBlogtoBlog