androidx.wear.compose.material.dialog


Objects

DialogDefaults

Contains the default values used by Alert and Confirmation.

Top-level functions summary

Unit
@Composable
Alert(
    title: @Composable ColumnScope.() -> Unit,
    modifier: Modifier,
    icon: (@Composable ColumnScope.() -> Unit)?,
    message: (@Composable ColumnScope.() -> Unit)?,
    scrollState: ScalingLazyListState,
    backgroundColor: Color,
    titleColor: Color,
    messageColor: Color,
    iconColor: Color,
    verticalArrangement: Arrangement.Vertical,
    contentPadding: PaddingValues,
    content: ScalingLazyListScope.() -> Unit
)

Alert lays out the content for an opinionated, alert screen.

Unit
@Composable
Alert(
    title: @Composable ColumnScope.() -> Unit,
    negativeButton: @Composable () -> Unit,
    positiveButton: @Composable () -> Unit,
    modifier: Modifier,
    icon: (@Composable ColumnScope.() -> Unit)?,
    scrollState: ScalingLazyListState,
    backgroundColor: Color,
    contentColor: Color,
    titleColor: Color,
    iconColor: Color,
    verticalArrangement: Arrangement.Vertical,
    contentPadding: PaddingValues,
    content: (@Composable ColumnScope.() -> Unit)?
)

Alert lays out the content for an opinionated, alert screen.

Unit
@Composable
Confirmation(
    onTimeout: () -> Unit,
    modifier: Modifier,
    icon: (@Composable ColumnScope.() -> Unit)?,
    scrollState: ScalingLazyListState,
    durationMillis: Long,
    backgroundColor: Color,
    contentColor: Color,
    iconColor: Color,
    verticalArrangement: Arrangement.Vertical,
    contentPadding: PaddingValues,
    content: @Composable ColumnScope.() -> Unit
)

Confirmation lays out the content for an opinionated confirmation screen that displays a message to the user for durationMillis.

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

Dialog displays a full-screen dialog, layered over any other content.

Top-level functions

@Composable
fun Alert(
    title: @Composable ColumnScope.() -> Unit,
    modifier: Modifier = Modifier,
    icon: (@Composable ColumnScope.() -> Unit)? = null,
    message: (@Composable ColumnScope.() -> Unit)? = null,
    scrollState: ScalingLazyListState = rememberScalingLazyListState(),
    backgroundColor: Color = MaterialTheme.colors.background,
    titleColor: Color = contentColorFor(backgroundColor),
    messageColor: Color = contentColorFor(backgroundColor),
    iconColor: Color = contentColorFor(backgroundColor),
    verticalArrangement: Arrangement.Vertical = DialogDefaults.AlertVerticalArrangement,
    contentPadding: PaddingValues = DialogDefaults.ContentPadding,
    content: ScalingLazyListScope.() -> Unit
): Unit

Alert lays out the content for an opinionated, alert screen. This overload offers 4 slots for title, optional icon, optional message text and a content slot expected to be one or more vertically stacked Chips or ToggleChips. Alert is scrollable by default if the content is taller than the viewport.

Alert can be used as a destination in a navigation graph e.g. using SwipeDismissableNavHost. However, for a conventional fullscreen dialog, displayed on top of other content, use Dialog.

Example of an Alert with an icon, title, message text and chips:

import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.wrapContentSize
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import androidx.wear.compose.material.Chip
import androidx.wear.compose.material.ChipDefaults
import androidx.wear.compose.material.Icon
import androidx.wear.compose.material.MaterialTheme
import androidx.wear.compose.material.Text
import androidx.wear.compose.material.dialog.Alert

Alert(
    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 " +
                "(swipe right to dismiss)",
            textAlign = TextAlign.Center,
            style = MaterialTheme.typography.body2
        )
    },
) {
    item {
        Chip(
            label = { Text("Primary") },
            onClick = { /* Do something e.g. navController.popBackStack() */ },
            colors = ChipDefaults.primaryChipColors(),
        )
    }
    item {
        Chip(
            label = { Text("Secondary") },
            onClick = { /* Do something e.g. navController.popBackStack() */ },
            colors = ChipDefaults.secondaryChipColors(),
        )
    }
}
Parameters
title: @Composable ColumnScope.() -> Unit

A slot for displaying the title of the dialog, expected to be one or two lines of text.

modifier: Modifier = Modifier

Modifier to be applied to the dialog.

icon: (@Composable ColumnScope.() -> Unit)? = null

Optional slot for an icon to be shown at the top of the dialog.

message: (@Composable ColumnScope.() -> Unit)? = null

Optional slot for additional message content, expected to be 2-3 lines of text.

scrollState: ScalingLazyListState = rememberScalingLazyListState()

The scroll state for the dialog so that the scroll position can be displayed e.g. by the PositionIndicator passed to Scaffold.

backgroundColor: Color = MaterialTheme.colors.background

Color representing the background color for the dialog.

titleColor: Color = contentColorFor(backgroundColor)

Color representing the color for title.

messageColor: Color = contentColorFor(backgroundColor)

Color representing the color for message.

iconColor: Color = contentColorFor(backgroundColor)

Color representing the color for icon.

verticalArrangement: Arrangement.Vertical = DialogDefaults.AlertVerticalArrangement

The vertical arrangement of the dialog's children. This allows us to add spacing between items and specify the arrangement of the items when we have not enough of them to fill the whole minimum size.

contentPadding: PaddingValues = DialogDefaults.ContentPadding

The padding to apply around the whole of the dialog's contents.

content: ScalingLazyListScope.() -> Unit

A slot for one or more spaced Chips, stacked vertically.

@Composable
fun Alert(
    title: @Composable ColumnScope.() -> Unit,
    negativeButton: @Composable () -> Unit,
    positiveButton: @Composable () -> Unit,
    modifier: Modifier = Modifier,
    icon: (@Composable ColumnScope.() -> Unit)? = null,
    scrollState: ScalingLazyListState = rememberScalingLazyListState(),
    backgroundColor: Color = MaterialTheme.colors.background,
    contentColor: Color = contentColorFor(backgroundColor),
    titleColor: Color = contentColor,
    iconColor: Color = contentColor,
    verticalArrangement: Arrangement.Vertical = DialogDefaults.AlertVerticalArrangement,
    contentPadding: PaddingValues = DialogDefaults.ContentPadding,
    content: (@Composable ColumnScope.() -> Unit)? = null
): Unit

Alert lays out the content for an opinionated, alert screen. This overload offers 5 slots for title, negative button, positive button, optional icon and optional content. The buttons are shown side-by-side below the icon, text and content. Alert is scrollable by default if the content is taller than the viewport.

Alert can be used as a destination in a navigation graph e.g. using SwipeDismissableNavHost. However, for a conventional fullscreen dialog, displayed on top of other content, use Dialog.

Example of an Alert with an icon, title, body text and buttons:

import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.wrapContentSize
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import androidx.wear.compose.material.Button
import androidx.wear.compose.material.ButtonDefaults
import androidx.wear.compose.material.Icon
import androidx.wear.compose.material.Text
import androidx.wear.compose.material.dialog.Alert

Alert(
    icon = {
        Icon(
            painter = painterResource(id = R.drawable.ic_airplanemode_active_24px),
            contentDescription = "airplane",
            modifier = Modifier.size(24.dp).wrapContentSize(align = Alignment.Center),
        )
    },
    title = { Text("Title text displayed here", textAlign = TextAlign.Center) },
    negativeButton = { Button(
        colors = ButtonDefaults.secondaryButtonColors(),
        onClick = {
            /* Do something e.g. navController.popBackStack()*/
        }) {
        Text("No")
    } },
    positiveButton = { Button(onClick = {
        /* Do something e.g. navController.popBackStack()*/
    }) { Text("Yes") } },
    contentPadding =
        PaddingValues(start = 10.dp, end = 10.dp, top = 24.dp, bottom = 32.dp),
) {
    Text(
        text = "Body text displayed here " +
               "(swipe right to dismiss)",
        textAlign = TextAlign.Center
    )
}
Parameters
title: @Composable ColumnScope.() -> Unit

A slot for displaying the title of the dialog, expected to be one or two lines of text.

negativeButton: @Composable () -> Unit

A slot for a Button indicating negative sentiment (e.g. No). Clicking the button must remove the dialog from the composition hierarchy.

positiveButton: @Composable () -> Unit

A slot for a Button indicating positive sentiment (e.g. Yes). Clicking the button must remove the dialog from the composition hierarchy.

modifier: Modifier = Modifier

Modifier to be applied to the dialog content.

icon: (@Composable ColumnScope.() -> Unit)? = null

Optional slot for an icon to be shown at the top of the dialog.

scrollState: ScalingLazyListState = rememberScalingLazyListState()

The scroll state for the dialog so that the scroll position can be displayed e.g. by the PositionIndicator passed to Scaffold.

backgroundColor: Color = MaterialTheme.colors.background

Color representing the background color for the dialog.

contentColor: Color = contentColorFor(backgroundColor)

Color representing the color for content.

titleColor: Color = contentColor

Color representing the color for title.

iconColor: Color = contentColor

Icon Color that defaults to contentColor, unless specifically overridden.

verticalArrangement: Arrangement.Vertical = DialogDefaults.AlertVerticalArrangement

The vertical arrangement of the dialog's children. This allows us to add spacing between items and specify the arrangement of the items when we have not enough of them to fill the whole minimum size.

contentPadding: PaddingValues = DialogDefaults.ContentPadding

The padding to apply around the whole of the dialog's contents.

content: (@Composable ColumnScope.() -> Unit)? = null

A slot for additional content, expected to be 2-3 lines of text.

@Composable
fun Confirmation(
    onTimeout: () -> Unit,
    modifier: Modifier = Modifier,
    icon: (@Composable ColumnScope.() -> Unit)? = null,
    scrollState: ScalingLazyListState = rememberScalingLazyListState(),
    durationMillis: Long = DialogDefaults.ShortDurationMillis,
    backgroundColor: Color = MaterialTheme.colors.background,
    contentColor: Color = contentColorFor(backgroundColor),
    iconColor: Color = contentColor,
    verticalArrangement: Arrangement.Vertical = DialogDefaults.ConfirmationVerticalArrangement,
    contentPadding: PaddingValues = DialogDefaults.ContentPadding,
    content: @Composable ColumnScope.() -> Unit
): Unit

Confirmation lays out the content for an opinionated confirmation screen that displays a message to the user for durationMillis. It has a slot for an icon or image (which could be animated).

Confirmation can be used as a destination in a navigation graph e.g. using SwipeDismissableNavHost. However, for a conventional fullscreen dialog, displayed on top of other content, use Dialog.

Example of a Confirmation with animation:

import androidx.compose.animation.graphics.res.animatedVectorResource
import androidx.compose.animation.graphics.res.rememberAnimatedVectorPainter
import androidx.compose.animation.graphics.vector.AnimatedImageVector
import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.size
import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import androidx.wear.compose.material.Text
import androidx.wear.compose.material.dialog.Confirmation

val animation = AnimatedImageVector.animatedVectorResource(R.drawable.open_on_phone_animation)
Confirmation(
    onTimeout = {
        /* Do something e.g. navController.popBackStack() */
    },
    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 = animation.totalDuration * 2L,
) {
    Text(
        text = "Body text displayed here " +
            "(swipe right to dismiss)",
        textAlign = TextAlign.Center
    )
}
Parameters
onTimeout: () -> Unit

Event invoked when the dialog has been shown for durationMillis.

modifier: Modifier = Modifier

Modifier to be applied to the dialog.

icon: (@Composable ColumnScope.() -> Unit)? = null

An optional slot for displaying an icon or image.

scrollState: ScalingLazyListState = rememberScalingLazyListState()

The scroll state for the dialog so that the scroll position can be displayed e.g. by the PositionIndicator passed to Scaffold.

durationMillis: Long = DialogDefaults.ShortDurationMillis

The number of milliseconds for which the dialog is displayed, must be positive. Suggested values are DialogDefaults.ShortDurationMillis, DialogDefaults.LongDurationMillis or DialogDefaults.IndefiniteDurationMillis.

backgroundColor: Color = MaterialTheme.colors.background

Color representing the background color for this dialog.

contentColor: Color = contentColorFor(backgroundColor)

Color representing the color for content.

iconColor: Color = contentColor

Icon Color that defaults to the contentColor, unless specifically overridden.

verticalArrangement: Arrangement.Vertical = DialogDefaults.ConfirmationVerticalArrangement

The vertical arrangement of the dialog's children. This allows us to add spacing between items and specify the arrangement of the items when we have not enough of them to fill the whole minimum size.

contentPadding: PaddingValues = DialogDefaults.ContentPadding

The padding to apply around the whole of the dialog's contents.

content: @Composable ColumnScope.() -> Unit

A slot for the dialog title, expected to be one line of text.

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

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.

Example of content using Dialog to trigger an alert dialog using Alert:

import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.wrapContentSize
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import androidx.wear.compose.foundation.lazy.rememberScalingLazyListState
import androidx.wear.compose.material.Chip
import androidx.wear.compose.material.ChipDefaults
import androidx.wear.compose.material.Icon
import androidx.wear.compose.material.MaterialTheme
import androidx.wear.compose.material.Text
import androidx.wear.compose.material.dialog.Alert
import androidx.wear.compose.material.dialog.Dialog

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(),
                )
            }
        }
    }
}

Example of content using Dialog to trigger a confirmation dialog using Confirmation:

import androidx.compose.animation.graphics.res.animatedVectorResource
import androidx.compose.animation.graphics.res.rememberAnimatedVectorPainter
import androidx.compose.animation.graphics.vector.AnimatedImageVector
import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import androidx.wear.compose.material.Chip
import androidx.wear.compose.material.ChipDefaults
import androidx.wear.compose.material.Text
import androidx.wear.compose.material.dialog.Confirmation
import androidx.wear.compose.material.dialog.Dialog

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)
        }
    }
}
Parameters
showDialog: Boolean

Controls 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 calls onDismissRequest and hides itself.

onDismissRequest: () -> Unit

Executes when the user dismisses the dialog. Must remove the dialog from the composition.

modifier: Modifier = Modifier

Modifier to be applied to the dialog.

scrollState: ScalingLazyListState? = rememberScalingLazyListState()

The scroll state for the dialog so that the scroll position can be displayed.

properties: DialogProperties = DialogProperties()

Typically platform specific properties to further configure the dialog.

content: @Composable () -> Unit

Slot for dialog content such as Alert or Confirmation.