Hands-on with Material Components for Android: Dialogs

Part 7 of a series covering practical usage of Material Components for Android

Nick Rout
Over Engineering

--

This post will be covering the features and API of Dialog components. To find out how to handle initial setup of Material Components for Android (including the Gradle dependency and creating an app theme), please see my original post:

Dialogs are components, typically with modal windows, that are displayed in front of app content. They are used to inform users about a task that may contain critical information and/or require a decision. They purposefully interrupt the current flow and remain on screen until dismissed or action has been taken, so they should be used sparingly.

From a design perspective, there are three main types of dialogs which can be used in different scenarios:

  • Alert dialog: The simplest of dialogs, despite the name. Used to interrupt a user with urgent information that typically requires user action/confirmation. Characterized by a title, optional supporting text and action buttons.
  • Simple dialog: Used to present the user with a list of actions that, when tapped, take immediate effect. Should not contain action buttons.
  • Confirmation dialog: Used to present a list of single- or multi-select choices to a user. Action buttons serve to confirm the choice(s).

All of the above share common characteristics: a background scrim that obscures app content (which can be optionally tapped to dismiss the dialog) and a surface container.

Note: A fourth type exists: Full screen dialog. To implement this, the official documentation recommends using a DialogFragment along with resource qualifiers to determine how it is presented. This is outside the scope of this article and won’t be covered.

Basic usage 🏁

All of the aforementioned dialog types can be implemented using MaterialAlertDialogBuilder. This builder class configures and instantiates an AlertDialog with Material Design specifications and theming.

The basic method of showing a dialog is like so:

// Note: A second constructor exists to pass in a theme res ID
MaterialAlertDialogBuilder(context)
// Add customization options here
.show()

The above approach will not retain the dialog after a configuration change (such as device rotation). To achieve this we need to use a DialogFragment while still using MaterialAlertDialogBuilder to provide the Dialog:

class AppDialogFragment : DialogFragment() {

override fun onCreateDialog(
savedInstanceState: Bundle?
): Dialog {
return MaterialAlertDialogBuilder(requireContext())
// Add customization options here
.create()
}
}

The DialogFragment can be shown using the Navigation Architecture Component or manually from a Fragment or Activity in the following way:

// Note: A FragmentTransaction can be used in place of the manager
AppDialogFragment().show(requireFragmentManager(), TAG)

Customization using the builder 🧰

All of the characteristics listed in the three types of dialogs above (and more) can be achieved by passing parameters to MaterialAlertDialogBuilder. Some of these are listed below.

Note: In most cases below, hardcoded values are used. The builder provides overloads for resource IDs as well.

Title and supporting text

// Title
.setTitle("Title")
// Supporting text
.setMessage("Supporting text")

Action buttons

// Confirming action
.setPositiveButton("Confirm") { dialog, which ->
// Do something for button click
}
// Dismissive action
.setNegativeButton("Dismiss") { dialog, which ->
// Do something for button click
}
// Neutral action
.setNeutralButton("Neutral") { dialog, which ->
// Do something for button click
}

Simple items

val items = arrayOf("Item 1", "Item 2", "Item 3").setItems(items) { dialog, which ->
// Do something for item chosen
}

Single- and multi-choice items

val singleItems = arrayOf("Item 1", "Item 2", "Item 3", "Item 4")
val checkedItem = 0
// Single-choice items (initialized with checked item)
.setSingleChoiceItems(singleItems, checkedItem) { dialog, which ->
// Do something for item chosen
}
val multiItems = arrayOf("Item 1", "Item 2", "Item 3", "Item 4")
val checkedItems = booleanArrayOf(true, false, false, false)
// Multi-choice items (initialized with checked items)
.setMultiChoiceItems(items, checkedItems) { dialog, which, checked ->
// Do something for item chosen
}

Icon

.setIcon(R.drawable.ic_android_24dp)

Custom layout/view

.setView(R.layout.view_custom_dialog)

Note: The middle area of the dialog can be occupied by either supporting text or a set of items of a particular type. These cannot be combined.

Choosing a theme overlay 🤔

A couple of theme overlays exist for changing the general layout of a dialog. These theme overlay variants inherit from ThemeOverlay.MaterialComponents.MaterialAlertDialog, each with an optional suffix:

  • Default: No suffix
  • Centered: *.Centered, center-aligned title and icon

When implementing a global custom Material AlertDialog theme overlay, reference it in your app theme with the materialAlertDialogTheme attribute.

Alternatively, there exists a secondary MaterialAlertDialogBuilder constructor which accepts an overriding theme resource ID:

MaterialAlertDialogBuilder(context, R.style.ThemeOverlay_MaterialComponents_MaterialAlertDialog)

Theming 🎨

Material Alert Dialogs can be themed in terms of the three Material Theming subsystems: color, typography and shape. We have already shown which theme overlays to use in the “Choosing a theme overlay” section above. In addition to this, a custom AlertDialog style can be referenced within a theme overlay by extending the MaterialAlertDialog.MaterialComponents style and using the alertDialogStyle attribute.

Color

There are no specific attributes to customize the colors used in a dialog but the colorPrimary, colorSecondary, colorSurface and respective “on” colors used in your app theme will automatically adjust the dialog colors when changed.

Color theming

Typography

The dialog text elements will adopt the fontFamily attribute defined in your app theme. The action buttons will be styled according to the textAppearanceButton style set in your app theme.

In your theme overlay, you can also use the materialAlertDialogBodyTextStyle attribute to specifically style the body text.

Type theming

Shape

The shape of a dialog background can be customized with the shapeAppearance attribute. This defaults to shapeAppearanceMediumComponent.

Shape theming

More resources 📚

I hope this post has provided some insight into dialogs and how they can be used in your Android app(s). If you have any questions, thoughts or suggestions then I’d love to hear from you!

Find me on Twitter @ricknout

--

--

Nick Rout
Over Engineering

Principal Android Engineer at GoDaddy | Ex-Google | Google Developer Expert for Android