Build apps faster with our new App builder! Check it out →

Dialog

Android

Component in Wear Material Compose

[Dialog] displays a full-screen dialog, layered over any other content. It takes a single slot, which is expected to be an opinionated Wear dialog content, such as [Alert] or [Confirmation].

The dialog supports swipe-to-dismiss and reveals the parent content in the background during the swipe gesture.

Last updated:

Installation

dependencies {
   implementation("androidx.wear.compose:compose-material:1.5.0-alpha04")
}

Overloads

@Composable
fun Dialog(
    showDialog: Boolean,
    onDismissRequest: () -> Unit,
    modifier: Modifier = Modifier,
    scrollState: ScalingLazyListState? = rememberScalingLazyListState(),
    properties: DialogProperties = DialogProperties(),
    content: @Composable () -> Unit,
)

Parameters

namedescription
showDialogControls whether to display the [Dialog]. Set to true initially to trigger an 'intro' animation and display the [Dialog]. Subsequently, setting to false triggers an 'outro' animation, then [Dialog] hides itself.
onDismissRequestExecutes when the user dismisses the dialog. Must remove the dialog from the composition.
modifierModifier to be applied to the dialog.
scrollStateThe scroll state for the dialog so that the scroll position can be displayed.
propertiesTypically platform specific properties to further configure the dialog.
contentSlot for dialog content such as [Alert] or [Confirmation].
@Suppress("DEPRECATION")
@Deprecated(
    "This overload is provided for backwards compatibility with Compose for Wear OS 1.1." +
        "A newer overload is available which uses ScalingLazyListState from " +
        "wear.compose.foundation.lazy package",
    level = DeprecationLevel.HIDDEN
)
@Composable
fun Dialog(
    showDialog: Boolean,
    onDismissRequest: () -> Unit,
    modifier: Modifier = Modifier,
    scrollState: androidx.wear.compose.material.ScalingLazyListState? =
        androidx.wear.compose.material.rememberScalingLazyListState(),
    properties: DialogProperties = DialogProperties(),
    content: @Composable () -> Unit,
)

Parameters

namedescription
showDialogControls whether to display the [Dialog]. Set to true initially to trigger an 'intro' animation and display the [Dialog]. Subsequently, setting to false triggers an 'outro' animation, then [Dialog] hides itself.
onDismissRequestExecutes when the user dismisses the dialog. Must remove the dialog from the composition.
modifierModifier to be applied to the dialog.
scrollStateThe scroll state for the dialog so that the scroll position can be displayed.
propertiesTypically platform specific properties to further configure the dialog.
contentSlot for dialog content such as [Alert] or [Confirmation].

Code Examples

AlertDialogSample

@Composable
fun AlertDialogSample() {
    Box {
        var showDialog by remember { mutableStateOf(false) }
        Column(
            modifier = Modifier.fillMaxSize().padding(horizontal = 20.dp),
            verticalArrangement = Arrangement.Center,
            horizontalAlignment = Alignment.CenterHorizontally
        ) {
            Chip(
                onClick = { showDialog = true },
                label = { Text("Show dialog") },
                colors = ChipDefaults.secondaryChipColors(),
            )
        }
        val scrollState = rememberScalingLazyListState()
        Dialog(
            showDialog = showDialog,
            onDismissRequest = { showDialog = false },
            scrollState = scrollState,
        ) {
            Alert(
                scrollState = scrollState,
                verticalArrangement = Arrangement.spacedBy(4.dp, Alignment.Top),
                contentPadding =
                    PaddingValues(start = 10.dp, end = 10.dp, top = 24.dp, bottom = 52.dp),
                icon = {
                    Icon(
                        painter = painterResource(id = R.drawable.ic_airplanemode_active_24px),
                        contentDescription = "airplane",
                        modifier = Modifier.size(24.dp).wrapContentSize(align = Alignment.Center),
                    )
                },
                title = { Text(text = "Example Title Text", textAlign = TextAlign.Center) },
                message = {
                    Text(
                        text = "Message content goes here",
                        textAlign = TextAlign.Center,
                        style = MaterialTheme.typography.body2
                    )
                },
            ) {
                item {
                    Chip(
                        label = { Text("Primary") },
                        onClick = { showDialog = false },
                        colors = ChipDefaults.primaryChipColors(),
                    )
                }
                item {
                    Chip(
                        label = { Text("Secondary") },
                        onClick = { showDialog = false },
                        colors = ChipDefaults.secondaryChipColors(),
                    )
                }
            }
        }
    }
}

ConfirmationDialogSample

@OptIn(ExperimentalAnimationGraphicsApi::class)
@Composable
fun ConfirmationDialogSample() {
    Box {
        var showDialog by remember { mutableStateOf(false) }
        Column(
            modifier = Modifier.fillMaxSize().padding(horizontal = 25.dp),
            verticalArrangement = Arrangement.Center,
            horizontalAlignment = Alignment.CenterHorizontally
        ) {
            Chip(
                onClick = { showDialog = true },
                label = { Text("Show dialog") },
                colors = ChipDefaults.secondaryChipColors(),
            )
        }
        Dialog(showDialog = showDialog, onDismissRequest = { showDialog = false }) {
            val animation =
                AnimatedImageVector.animatedVectorResource(R.drawable.open_on_phone_animation)
            Confirmation(
                onTimeout = { showDialog = false },
                icon = {
                    // Initially, animation is static and shown at the start position (atEnd =
                    // false).
                    // Then, we use the EffectAPI to trigger a state change to atEnd = true,
                    // which plays the animation from start to end.
                    var atEnd by remember { mutableStateOf(false) }
                    DisposableEffect(Unit) {
                        atEnd = true
                        onDispose {}
                    }
                    Image(
                        painter = rememberAnimatedVectorPainter(animation, atEnd),
                        contentDescription = "Open on phone",
                        modifier = Modifier.size(48.dp)
                    )
                },
                durationMillis = 3000,
            ) {
                Text(text = "Open on phone", textAlign = TextAlign.Center)
            }
        }
    }
}
by @alexstyl