Alert Dialogs in Android

In this post I will look at the basics of making alert dialogs appear on Android.

An example Android Studio project demonstrating the code shown here is available on GitHub.

Overview

Android provides the AlertDialog class for creating dialog boxes with a simple structure of a title, content (typically a text-based message), and up to three action buttons.

An instance of AlertDialog is created (using the provided Builder class) and various setter methods are used to create our design, which can then be shown with the show() method.

Methods of AlertDialog

Builder(Context)Nested class, who's create() method returns a new AlertDialog object. Context parameter should be the current activity object, eg. MainActivity.this
setTitle(CharSequence)Sets the title text for the alert dialog
setMessage(CharSequence)Sets the message text
setButton(int whichButton, CharSequence text, DialogInterface.OnClickListener listener) Sets the button caption and listener to be called when button is pressed
setCanceledOnTouchOutside(boolean)When set to true user can dismiss dialog by touching elsewhere on the display
setOnCancelListener(DialogInterface.OnCancelListener) Set listener to be called if dialog is cancelled by touching outside
show()Causes the alert dialog to appear and take focus
dismiss()Make the dialog go away and return focus to the activity

Dialogues of Alert

The No-Button Alert

What happens if we don't set any buttons?

The simplest alert dialog we can make doesn't have any buttons, so it's a good place to start. However with no buttons, how can the user dismiss the dialog?

Alert dialogs can optionally be cancelled when the user touches outside the dialog - enabling this with the setCanceledOnTouchOutside() method, it will be possible to dismiss the dialog.

For this example it will be neccesary to import android.app.AlertDialog

AlertDialog alertDialog = new AlertDialog.Builder(MainActivity.this).create();
alertDialog.setTitle("Alert Title");
alertDialog.setMessage("Touch outside to dismiss");
alertDialog.setCanceledOnTouchOutside(true);
alertDialog.show();

Placed in a method in your activity class, the above code is all that is needed to show this most basic alert dialog.

You can also use setCanceledOnTouchOutside(false) which will prevent the user from dismissing the dialog, so long as you arrange to dismiss it from code elsewhere, which I will cover below.

One Button Alert

To make it a proper dialog box we need a button for the user to acknowledge it, and a way to run code in response.

A button can be added with the setButton() method. The first argument specifies the type of button and must be one of AlertDialog.BUTTON_NEUTRAL, AlertDialog.BUTTON_NEGATIVE, or AlertDialog.BUTTON_POSITIVE. This will make sense when we make a 3 button alert, below.

To run code in response to the button we need to implement the onClick method of the DialogInterface.OnClickListener interface, and pass the listener in when we call setButton.

We now need to import android.content.DialogInterface in addition to android.app.AlertDialog

DialogInterface.OnClickListener listener = new DialogInterface.OnClickListener() {
    @Override
    public void onClick(DialogInterface dialog, int which) {
        dialog.dismiss();
        // do stuff
    }
};

AlertDialog alertDialog = new AlertDialog.Builder(MainActivity.this).create();
alertDialog.setTitle("Alert Title");
alertDialog.setMessage("Please press ok.");

// add a button, with button text and reference to click event listener
alertDialog.setButton(AlertDialog.BUTTON_NEUTRAL, "Ok", listener);

alertDialog.show();

Alerts With More Buttons

Alert Dialogs can have up to 3 buttons. Each additional button is set with a call to setButton() - this is where the three types of BUTTON_NEUTRAL, BUTTON_NEGATIVE and BUTTON_POSITIVE come in - you can have one of each. The button texts can be anything you like but these notionally correspond to "cancel" "no" and "yes" respectively.

You can either pass each button the same listener and tell them apart with the which argument in the onClick method (as shown), or you can pass each button it's own listener callback.

DialogInterface.OnClickListener listener = new DialogInterface.OnClickListener() {
    @Override
    public void onClick(DialogInterface dialog, int which) {
        dialog.dismiss();
        switch (which) {
            case AlertDialog.BUTTON_NEUTRAL:
                // do neutral stuff
                break;
            case AlertDialog.BUTTON_NEGATIVE:
                // do negative stuff
                break;
            case AlertDialog.BUTTON_POSITIVE:
                // do positive stuff
                break;
        }
    }
};

AlertDialog alertDialog = new AlertDialog.Builder(MainActivity.this).create();
alertDialog.setTitle("Alert Title");
alertDialog.setMessage("Choose cancel, yes or no.");
alertDialog.setButton(AlertDialog.BUTTON_NEUTRAL, "Cancel", listener);
alertDialog.setButton(AlertDialog.BUTTON_NEGATIVE, "No", listener);
alertDialog.setButton(AlertDialog.BUTTON_POSITIVE, "Yes", listener);
alertDialog.show();

On Cancel Listener

As mentioned at the start, Android allows dialogs to be cancelled simply by the user tapping outside the dialog window. If you try the above button examples, you will find that in this case the listener is not called at all. What do we do then to determine the user response? We're in luck as Alert dialogs also allow you to set an OnCancelListener that will be called if the user does just this.

DialogInterface.OnClickListener listener = new DialogInterface.OnClickListener() {
    @Override
    public void onClick(DialogInterface dialog, int which) {
        dialog.dismiss();
        // do stuff
    }
};
DialogInterface.OnCancelListener cancelListener = new DialogInterface.OnCancelListener() {
    @Override
    public void onCancel(DialogInterface dialog) {
        // do cancel stuff
    }
};

AlertDialog alertDialog = new AlertDialog.Builder(MainActivity.this).create();
alertDialog.setTitle("Alert with Cancel Listener");
alertDialog.setMessage("Tap yes or tap outside to cancel");
alertDialog.setButton(AlertDialog.BUTTON_POSITIVE, "Yes", listener);

/* make sure user can cancel by touching outside, and set listener for this event */
alertDialog.setCanceledOnTouchOutside(true);
alertDialog.setOnCancelListener(cancelListener);

alertDialog.show();

Advanced

As hinted at above, it is possible to create an alert dialog with no buttons, and by disabling the touch outside to cancel behaviour, there would be no way to dismiss the dialog. Can we make any use of this?

As it turns out, yes. So long as we hold on to a reference to the AlertDialog object used to create the dialog, we can dismiss it from code at some later time. We could for example use this to make the user wait while some process is completed. The dialog text can even be modified to keep the user updated while they wait.

For an example of this, see the MoreAlert activity in the linked example project.