Dialog & AlertDialog APIs in Jetpack Compose (with Examples)

Jetpack Compose Dialog

In this article, we will learn how to work with Dialog and AlertDialog APIs in Jetpack Compose.

Prerequisites:

For this article, create an empty Jetpack Compose project and open MainActivity. Create a composable called MyUI() and call it from the onCreate().

import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.*
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp
import androidx.compose.ui.window.Dialog
import androidx.compose.ui.window.DialogProperties

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            YourProjectNameTheme(darkTheme = false) {
                Surface(
                    modifier = Modifier.fillMaxSize(),
                    color = MaterialTheme.colors.background
                ) {
                    Column(
                        modifier = Modifier.fillMaxSize(),
                        verticalArrangement = Arrangement.Center,
                        horizontalAlignment = Alignment.CenterHorizontally
                    ) {
                        MyUI()
                    }
                }
            }
        }
    }
}

@Composable
fun MyUI() {
  
}

We will write our code in the MyUI().

Jetpack Compose provides 2 Dialog APIs:

  1. AlertDialog
  2. Dialog

1. AlertDialog:

We can use it to make popup dialogs. Start typing AlertDialog and select the one with confirm and dismiss buttons.

Dialog Dismiss Button

It takes multiple parameters:

@Composable
fun AlertDialog(
    onDismissRequest: () -> Unit,
    confirmButton: @Composable () -> Unit,
    modifier: Modifier = Modifier,
    dismissButton: @Composable (() -> Unit)? = null,
    title: @Composable (() -> Unit)? = null,
    text: @Composable (() -> Unit)? = null,
    shape: Shape = MaterialTheme.shapes.medium,
    backgroundColor: Color = MaterialTheme.colors.surface,
    contentColor: Color = contentColorFor(backgroundColor),
    properties: DialogProperties = DialogProperties()
)

onDismissRequest – A lambda that is called when the user dismisses the dialog. It can be triggered when the user presses the back button or clicks outside the dialog. It is not called if you tap on the dismissButton.

confirmButton – A button for confirming an action. We use TextButton API.

modifier – To modify the layout of the dialog.

dismissButton – A button for dismissing the dialog. It is also a TextButton.

title – The title of the action. We add Text() composable here.

text – Description of the action. We also add Text() composable here.

shape – To set the shape for the dialog.

backgroundColor – The background color of the dialog.

contentColor – The dialog’s children’s preferred color.

properties – Additional configuration options.

Here is a simple example:

@Composable
fun MyUI() {
    var dialogOpen by remember {
        mutableStateOf(false)
    }

    if (dialogOpen) {
        AlertDialog(
            onDismissRequest = {
                // Dismiss the dialog when the user clicks outside the dialog or on the back button.
                // If you want to disable that functionality, simply leave this block empty.
                dialogOpen = false
            },
            confirmButton = {
                TextButton(
                    onClick = {
                        // perform the confirm action and
                        // close the dialog
                        dialogOpen = false
                    }
                ) {
                    Text(text = "Confirm")
                }
            },
            dismissButton = {
                TextButton(
                    onClick = {
                        // close the dialog
                        dialogOpen = false
                    }
                ) {
                    Text(text = "Dismiss")
                }
            },
            title = {
                Text(text = "Title")
            },
            text = {
                Text(text = "Description")
            },
            modifier = Modifier
                .fillMaxWidth()
                .padding(32.dp),
            shape = RoundedCornerShape(5.dp),
            backgroundColor = Color.White
        )
    }

    Button(
        onClick = { dialogOpen = true }
    ) {
        Text(text = "SHOW DIALOG")
    }
}

Output:

Jetpack Compose Dialog Example

By default, it places the buttons horizontally next to each other. There is another overload that provides the custom layout for the buttons. Start typing AlertDialog and select the one with the buttons parameter.

buttons parameter

Example:

@Composable
fun MyUI() {
    var dialogOpen by remember {
        mutableStateOf(false)
    }

    if (dialogOpen) {
        AlertDialog(
            onDismissRequest = {
                // Dismiss the dialog when the user clicks outside the dialog or on the back button.
                // If you want to disable that functionality, simply leave this block empty.
                dialogOpen = false
            },
            buttons = {
                Column(
                    modifier = Modifier
                        .fillMaxWidth()
                        .padding(bottom = 24.dp),
                    horizontalAlignment = Alignment.CenterHorizontally
                ) {
                    // confirm button
                    Button(
                        onClick = {
                            dialogOpen = false
                        }
                    ) {
                        Text(text = "Confirm")
                    }

                    // dismiss button
                    Button(
                        onClick = {
                            dialogOpen = false
                        }
                    ) {
                        Text(text = "Dismiss")
                    }
                }
            },
            title = {
                Text(text = "Title")
            },
            text = {
                Text(text = "Description")
            },
            modifier = Modifier
                .fillMaxWidth()
                .padding(32.dp),
            shape = RoundedCornerShape(5.dp),
            backgroundColor = Color.White
        )
    }

    Button(onClick = { dialogOpen = true }) {
        Text(text = "SHOW DIALOG")
    }
}

Output:

AlertDialog button positions

2. Dialog:

The Dialog API provides the functionality to create custom dialogs.

@Composable
fun Dialog(
    onDismissRequest: () -> Unit,
    properties: DialogProperties = DialogProperties(),
    content: @Composable () -> Unit
)

Example:

@Composable
fun MyUI() {

    var dialogOpen by remember {
        mutableStateOf(false)
    }

    if (dialogOpen) {
        Dialog(onDismissRequest = {
            dialogOpen = false
        }) {
            Surface(
                modifier = Modifier
                    .fillMaxWidth()
                    .wrapContentHeight(),
                shape = RoundedCornerShape(size = 10.dp)
            ) {
                Column(modifier = Modifier.padding(all = 16.dp)) {
                    Text(text = "Your Dialog UI Here")
                }
            }
        }
    }

    Button(onClick = { dialogOpen = true }) {
        Text(text = "OPEN")
    }
}

Output:

Custom Dialog

Related: Look at these awesome custom dialogs made with Jetpack Compose.

Dialog Properties:

The DialogProperties() class facilitates closing the dialog when the user clicks outside it or presses the back button.

class DialogProperties constructor(
    val dismissOnBackPress: Boolean = true,
    val dismissOnClickOutside: Boolean = true,
    val securePolicy: SecureFlagPolicy = SecureFlagPolicy.Inherit,
    val usePlatformDefaultWidth: Boolean = true
)

dismissOnBackPress – If the dialog should be dismissed when the user presses the back button. If it is true, pressing the back button will call onDismissRequest.

dismissOnClickOutside – If the dialog should be dismissed when the user clicks outside the dialog. If it is true, clicking outside the dialog will call onDismissRequest.

securePolicy – Policy for setting FLAG_SECURE on the dialog’s window.

usePlatformDefaultWidth – If the dialog should use the platform’s default width which is smaller than the screen size. If you want to create a full screen dialog, set its value to false. This is experimental.

Create its object and pass it to the properties parameter. Both the AlertDialog() and Dialog() composables accept properties parameter.

@Composable
fun MyUI() {
    var dialogOpen by remember {
        mutableStateOf(false)
    }

    if (dialogOpen) {
        Dialog(
            onDismissRequest = {
                dialogOpen = false
            },
            properties = DialogProperties(
                dismissOnClickOutside = false
            )
        ) {
            Surface(
                modifier = Modifier
                    .fillMaxWidth()
                    .wrapContentHeight(),
                shape = RoundedCornerShape(size = 10.dp)
            ) {
                Column(modifier = Modifier.padding(all = 16.dp)) {
                    Text(text = "You cannot close me by clicking outside")
                }
            }
        }
    }

    Button(onClick = { dialogOpen = true }) {
        Text(text = "SHOW DIALOG")
    }
}

Output:

Jetpack Compose Dialog Properties

Related Articles:

References:

Leave a Comment