AlertDialog in Jetpack Compose: Usage, Customization, and Examples

In modern Android development with Jetpack Compose, displaying dialogs is a common requirement. AlertDialog is a versatile composable used to show alerts, confirmations, or any form of modal UI to the user. Jetpack Compose simplifies the process of creating and customizing dialogs, offering more flexibility and control compared to traditional Android development.

What is an AlertDialog?

An AlertDialog is a modal dialog that appears on top of the activity window. It’s commonly used to interrupt the user with critical information, require a decision, or confirm an action. With Jetpack Compose, you can easily create and customize AlertDialogs to fit your application’s design and functionality.

Why Use AlertDialog in Jetpack Compose?

  • Modularity: Compose simplifies the creation of dialogs, making code cleaner and more readable.
  • Customization: Compose provides greater flexibility in styling and theming your dialogs.
  • Reusability: You can easily create reusable dialog components to maintain consistency throughout your app.

Basic AlertDialog Implementation

Here’s a simple example of implementing an AlertDialog in Jetpack Compose:


import androidx.compose.material.AlertDialog
import androidx.compose.material.Text
import androidx.compose.material.Button
import androidx.compose.runtime.*
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Surface

@Composable
fun SimpleAlertDialog() {
    var showDialog by remember { mutableStateOf(false) }

    Button(onClick = { showDialog = true }) {
        Text("Show Dialog")
    }

    if (showDialog) {
        AlertDialog(
            onDismissRequest = { showDialog = false },
            title = { Text("Alert Dialog Title") },
            text = { Text("This is a basic alert dialog in Jetpack Compose.") },
            confirmButton = {
                Button(onClick = { showDialog = false }) {
                    Text("Confirm")
                }
            },
            dismissButton = {
                Button(onClick = { showDialog = false }) {
                    Text("Dismiss")
                }
            }
        )
    }
}

@Preview(showBackground = true)
@Composable
fun DefaultPreview() {
    MaterialTheme {
        Surface(color = MaterialTheme.colors.background) {
            SimpleAlertDialog()
        }
    }
}

Explanation:

  • A MutableState variable showDialog is used to control the visibility of the dialog.
  • When the button is clicked, showDialog is set to true, displaying the AlertDialog.
  • AlertDialog takes parameters like onDismissRequest, title, text, confirmButton, and dismissButton.
  • onDismissRequest is a callback that’s invoked when the user tries to dismiss the dialog by tapping outside it or pressing the back button.
  • confirmButton and dismissButton define the actions the user can take within the dialog.

Customizing AlertDialog

Jetpack Compose allows extensive customization of AlertDialogs. Here’s how to modify the title, text, buttons, and add more advanced features.

Changing the Title and Text


import androidx.compose.material.AlertDialog
import androidx.compose.material.Text
import androidx.compose.material.Button
import androidx.compose.runtime.*
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Surface

@Composable
fun CustomTitleTextAlertDialog() {
    var showDialog by remember { mutableStateOf(false) }

    Button(onClick = { showDialog = true }) {
        Text("Show Dialog")
    }

    if (showDialog) {
        AlertDialog(
            onDismissRequest = { showDialog = false },
            title = {
                Text(
                    text = "Custom Alert Title",
                    style = MaterialTheme.typography.h6
                )
            },
            text = {
                Text(
                    text = "This dialog has custom styling for the title and text using MaterialTheme."
                )
            },
            confirmButton = {
                Button(onClick = { showDialog = false }) {
                    Text("Confirm")
                }
            },
            dismissButton = {
                Button(onClick = { showDialog = false }) {
                    Text("Dismiss")
                }
            }
        )
    }
}

@Preview(showBackground = true)
@Composable
fun CustomTitleTextPreview() {
    MaterialTheme {
        Surface(color = MaterialTheme.colors.background) {
            CustomTitleTextAlertDialog()
        }
    }
}

Here, the title’s style is customized using MaterialTheme.typography.h6, and the text content is also defined.

Customizing Buttons

You can customize the look and feel of the confirm and dismiss buttons:


import androidx.compose.material.AlertDialog
import androidx.compose.material.Text
import androidx.compose.material.Button
import androidx.compose.material.ButtonDefaults
import androidx.compose.runtime.*
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Surface
import androidx.compose.ui.graphics.Color

@Composable
fun CustomButtonAlertDialog() {
    var showDialog by remember { mutableStateOf(false) }

    Button(onClick = { showDialog = true }) {
        Text("Show Dialog")
    }

    if (showDialog) {
        AlertDialog(
            onDismissRequest = { showDialog = false },
            title = { Text("Custom Buttons Dialog") },
            text = { Text("This dialog has custom styled buttons.") },
            confirmButton = {
                Button(
                    onClick = { showDialog = false },
                    colors = ButtonDefaults.buttonColors(backgroundColor = Color.Green, contentColor = Color.White)
                ) {
                    Text("Confirm")
                }
            },
            dismissButton = {
                Button(
                    onClick = { showDialog = false },
                    colors = ButtonDefaults.buttonColors(backgroundColor = Color.Red, contentColor = Color.White)
                ) {
                    Text("Dismiss")
                }
            }
        )
    }
}

@Preview(showBackground = true)
@Composable
fun CustomButtonPreview() {
    MaterialTheme {
        Surface(color = MaterialTheme.colors.background) {
            CustomButtonAlertDialog()
        }
    }
}

In this example, the colors of the buttons are changed using ButtonDefaults.buttonColors.

Adding an Icon

You can include an icon to make the dialog more visually appealing:


import androidx.compose.material.AlertDialog
import androidx.compose.material.Text
import androidx.compose.material.Button
import androidx.compose.material.Icon
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Warning
import androidx.compose.runtime.*
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Surface

@Composable
fun IconAlertDialog() {
    var showDialog by remember { mutableStateOf(false) }

    Button(onClick = { showDialog = true }) {
        Text("Show Dialog")
    }

    if (showDialog) {
        AlertDialog(
            onDismissRequest = { showDialog = false },
            icon = { Icon(imageVector = Icons.Filled.Warning, contentDescription = "Warning Icon") },
            title = { Text("Dialog with Icon") },
            text = { Text("This dialog includes an icon for better visual communication.") },
            confirmButton = {
                Button(onClick = { showDialog = false }) {
                    Text("Confirm")
                }
            },
            dismissButton = {
                Button(onClick = { showDialog = false }) {
                    Text("Dismiss")
                }
            }
        )
    }
}

@Preview(showBackground = true)
@Composable
fun IconPreview() {
    MaterialTheme {
        Surface(color = MaterialTheme.colors.background) {
            IconAlertDialog()
        }
    }
}

The icon parameter is used to include an icon in the dialog.

Advanced Customization

Using a Custom Layout

For complex UIs, you can use a custom layout inside the AlertDialog‘s text parameter:


import androidx.compose.material.AlertDialog
import androidx.compose.material.Text
import androidx.compose.material.Button
import androidx.compose.runtime.*
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Surface
import androidx.compose.foundation.layout.*
import androidx.compose.material.TextField
import androidx.compose.ui.Alignment
import androidx.compose.ui.unit.dp

@Composable
fun CustomLayoutAlertDialog() {
    var showDialog by remember { mutableStateOf(false) }
    var textValue by remember { mutableStateOf("") }

    Button(onClick = { showDialog = true }) {
        Text("Show Dialog")
    }

    if (showDialog) {
        AlertDialog(
            onDismissRequest = { showDialog = false },
            title = { Text("Custom Layout Dialog") },
            text = {
                Column(
                    horizontalAlignment = Alignment.CenterHorizontally,
                    verticalArrangement = Arrangement.spacedBy(8.dp)
                ) {
                    Text("Enter some text:")
                    TextField(
                        value = textValue,
                        onValueChange = { textValue = it },
                        label = { Text("Input") }
                    )
                }
            },
            confirmButton = {
                Button(onClick = {
                    showDialog = false
                    // Process the textValue
                }) {
                    Text("Confirm")
                }
            },
            dismissButton = {
                Button(onClick = { showDialog = false }) {
                    Text("Dismiss")
                }
            }
        )
    }
}

@Preview(showBackground = true)
@Composable
fun CustomLayoutPreview() {
    MaterialTheme {
        Surface(color = MaterialTheme.colors.background) {
            CustomLayoutAlertDialog()
        }
    }
}

Here, a Column containing a TextField is used to create a custom layout inside the dialog.

Conclusion

Jetpack Compose offers a powerful and flexible way to create and customize AlertDialogs. By using the various customization options, you can design dialogs that fit seamlessly into your app’s UI, providing a better user experience. Whether it’s a simple confirmation dialog or a complex input form, Compose’s AlertDialog can handle it with ease.