RichTimePickerDialog

Functions summary

Unit
@Composable
RichTimePickerDialog(
    onDismissRequest: () -> Unit,
    confirmButton: @Composable () -> Unit,
    modifier: Modifier,
    properties: DialogProperties,
    modeToggleButton: (@Composable () -> Unit)?,
    dismissButton: (@Composable () -> Unit)?,
    shape: Shape,
    containerColor: Color,
    content: @Composable ColumnScope.() -> Unit
)

Material Design rich time picker dialog

Cmn

Functions

RichTimePickerDialog

@Composable
fun RichTimePickerDialog(
    onDismissRequest: () -> Unit,
    confirmButton: @Composable () -> Unit,
    modifier: Modifier = Modifier,
    properties: DialogProperties = DialogProperties(usePlatformDefaultWidth = false),
    modeToggleButton: (@Composable () -> Unit)? = null,
    dismissButton: (@Composable () -> Unit)? = null,
    shape: Shape = TimePickerDialogDefaults.richShape,
    containerColor: Color = TimePickerDialogDefaults.richContainerColor,
    content: @Composable ColumnScope.() -> Unit
): Unit

Material Design rich time picker dialog

RichTimePickerDialog is a dialog container for a time picker. It is only responsible for the dialog's window chrome and actions (e.g. buttons) and does not include the time picker controls themselves. The time picker controls (e.g. TimePicker, TimeInput, or TimeScroll) should be provided in the content slot.

Rich time picker dialogs have a more prominent layout and are suitable for larger screens or situations where the time picker is the main focus of the UI.

A rich TimePicker with clock display input looks like:

import androidx.compose.foundation.layout.Box
import androidx.compose.material3.Button
import androidx.compose.material3.RichTimePickerDialog
import androidx.compose.material3.SnackbarHost
import androidx.compose.material3.SnackbarHostState
import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
import androidx.compose.material3.TimePicker
import androidx.compose.material3.TimePickerDefaults
import androidx.compose.material3.TimePickerDialog
import androidx.compose.material3.isInputValid
import androidx.compose.material3.rememberTimePickerState
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier

var showTimePicker by remember { mutableStateOf(false) }
val state = rememberTimePickerState()
val formatter = remember { SimpleDateFormat("hh:mm a", Locale.getDefault()) }
val snackState = remember { SnackbarHostState() }
val snackScope = rememberCoroutineScope()
Box(propagateMinConstraints = false) {
    Button(modifier = Modifier.align(Alignment.Center), onClick = { showTimePicker = true }) {
        Text("Set Time")
    }
    SnackbarHost(hostState = snackState)
}
if (showTimePicker) {
    RichTimePickerDialog(
        onDismissRequest = { showTimePicker = false },
        confirmButton = {
            TextButton(
                enabled = state.isInputValid,
                onClick = {
                    val cal = Calendar.getInstance()
                    cal.set(Calendar.HOUR_OF_DAY, state.hour)
                    cal.set(Calendar.MINUTE, state.minute)
                    cal.isLenient = false
                    snackScope.launch {
                        snackState.showSnackbar("Entered time: ${formatter.format(cal.time)}")
                    }
                    showTimePicker = false
                },
            ) {
                Text("OK")
            }
        },
        dismissButton = { TextButton(onClick = { showTimePicker = false }) { Text("Cancel") } },
    ) {
        TimePicker(state = state, shapes = TimePickerDefaults.shapes())
    }
}

A rich TimePicker with a UI of a text input mode looks like:

import androidx.compose.foundation.layout.Box
import androidx.compose.material3.Button
import androidx.compose.material3.RichTimePickerDialog
import androidx.compose.material3.SnackbarHost
import androidx.compose.material3.SnackbarHostState
import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
import androidx.compose.material3.TimeInput
import androidx.compose.material3.TimePicker
import androidx.compose.material3.TimePickerDefaults
import androidx.compose.material3.TimePickerDialog
import androidx.compose.material3.isInputValid
import androidx.compose.material3.rememberTimePickerState
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier

var showTimePicker by remember { mutableStateOf(false) }
val state = rememberTimePickerState()
val formatter = remember { SimpleDateFormat("hh:mm a", Locale.getDefault()) }
val snackState = remember { SnackbarHostState() }
val snackScope = rememberCoroutineScope()
Box(propagateMinConstraints = false) {
    Button(modifier = Modifier.align(Alignment.Center), onClick = { showTimePicker = true }) {
        Text("Set Input")
    }
    SnackbarHost(hostState = snackState)
}
if (showTimePicker) {
    RichTimePickerDialog(
        onDismissRequest = { showTimePicker = false },
        confirmButton = {
            TextButton(
                enabled = state.isInputValid,
                onClick = {
                    val cal = Calendar.getInstance()
                    cal.set(Calendar.HOUR_OF_DAY, state.hour)
                    cal.set(Calendar.MINUTE, state.minute)
                    cal.isLenient = false
                    snackScope.launch {
                        snackState.showSnackbar("Entered time: ${formatter.format(cal.time)}")
                    }
                    showTimePicker = false
                },
            ) {
                Text("OK")
            }
        },
        dismissButton = { TextButton(onClick = { showTimePicker = false }) { Text("Cancel") } },
    ) {
        TimeInput(state = state, shapes = TimePickerDefaults.shapes())
    }
}

A rich TimePicker with an initial UI of a clock display input that can switch to a text input mode looks like:

import androidx.compose.foundation.layout.Box
import androidx.compose.material3.Button
import androidx.compose.material3.RichTimePickerDialog
import androidx.compose.material3.SnackbarHost
import androidx.compose.material3.SnackbarHostState
import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
import androidx.compose.material3.TimeInput
import androidx.compose.material3.TimePicker
import androidx.compose.material3.TimePickerDefaults
import androidx.compose.material3.TimePickerDialog
import androidx.compose.material3.TimePickerDialogDefaults
import androidx.compose.material3.TimePickerDialogDefaults.MinHeightForTimePicker
import androidx.compose.material3.TimePickerDisplayMode
import androidx.compose.material3.isInputValid
import androidx.compose.material3.rememberTimePickerState
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalConfiguration
import androidx.compose.ui.unit.dp

var showTimePicker by remember { mutableStateOf(false) }
val state = rememberTimePickerState()
val formatter = remember { SimpleDateFormat("hh:mm a", Locale.getDefault()) }
val snackState = remember { SnackbarHostState() }
var displayMode by remember { mutableStateOf(TimePickerDisplayMode.Picker) }
val snackScope = rememberCoroutineScope()
val configuration = LocalConfiguration.current
Box(propagateMinConstraints = false) {
    Button(modifier = Modifier.align(Alignment.Center), onClick = { showTimePicker = true }) {
        Text("Set Time (Switchable)")
    }
    SnackbarHost(hostState = snackState)
}
if (showTimePicker) {
    RichTimePickerDialog(
        onDismissRequest = { showTimePicker = false },
        confirmButton = {
            TextButton(
                enabled = state.isInputValid,
                onClick = {
                    val cal = Calendar.getInstance()
                    cal.set(Calendar.HOUR_OF_DAY, state.hour)
                    cal.set(Calendar.MINUTE, state.minute)
                    cal.isLenient = false
                    snackScope.launch {
                        snackState.showSnackbar("Entered time: ${formatter.format(cal.time)}")
                    }
                    showTimePicker = false
                },
            ) {
                Text("OK")
            }
        },
        dismissButton = { TextButton(onClick = { showTimePicker = false }) { Text("Cancel") } },
        modeToggleButton = {
            if (configuration.screenHeightDp.dp > MinHeightForTimePicker) {
                TimePickerDialogDefaults.DisplayModeToggle(
                    onDisplayModeChange = {
                        displayMode =
                            if (displayMode == TimePickerDisplayMode.Picker) {
                                TimePickerDisplayMode.Input
                            } else {
                                TimePickerDisplayMode.Picker
                            }
                    },
                    displayMode = displayMode,
                )
            }
        },
    ) {
        if (
            displayMode == TimePickerDisplayMode.Picker &&
                configuration.screenHeightDp.dp > MinHeightForTimePicker
        ) {
            TimePicker(state = state, shapes = TimePickerDefaults.shapes())
        } else {
            TimeInput(state = state, shapes = TimePickerDefaults.shapes())
        }
    }
}

A rich TimePicker with an initial UI of a scrollable time input that can switch to a text input mode looks like:

import androidx.compose.foundation.layout.Box
import androidx.compose.material3.Button
import androidx.compose.material3.RichTimePickerDialog
import androidx.compose.material3.SnackbarHost
import androidx.compose.material3.SnackbarHostState
import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
import androidx.compose.material3.TimeInput
import androidx.compose.material3.TimePicker
import androidx.compose.material3.TimePickerDefaults
import androidx.compose.material3.TimePickerDialog
import androidx.compose.material3.TimePickerDialogDefaults
import androidx.compose.material3.TimePickerDisplayMode
import androidx.compose.material3.TimeScroll
import androidx.compose.material3.isInputValid
import androidx.compose.material3.rememberTimePickerState
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier

var showTimePicker by remember { mutableStateOf(false) }
val state = rememberTimePickerState()
val formatter = remember { SimpleDateFormat("hh:mm a", Locale.getDefault()) }
val snackState = remember { SnackbarHostState() }
var displayMode by remember { mutableStateOf(TimePickerDisplayMode.Scroll) }
val snackScope = rememberCoroutineScope()

Box(propagateMinConstraints = false) {
    Button(modifier = Modifier.align(Alignment.Center), onClick = { showTimePicker = true }) {
        Text("Set Time (Switchable, Scroll)")
    }
    SnackbarHost(hostState = snackState)
}

if (showTimePicker) {
    RichTimePickerDialog(
        onDismissRequest = { showTimePicker = false },
        confirmButton = {
            TextButton(
                enabled = state.isInputValid,
                onClick = {
                    val cal = Calendar.getInstance()
                    cal.set(Calendar.HOUR_OF_DAY, state.hour)
                    cal.set(Calendar.MINUTE, state.minute)
                    cal.isLenient = false
                    snackScope.launch {
                        snackState.showSnackbar("Entered time: ${formatter.format(cal.time)}")
                    }
                    showTimePicker = false
                },
            ) {
                Text("OK")
            }
        },
        dismissButton = { TextButton(onClick = { showTimePicker = false }) { Text("Cancel") } },
        modeToggleButton = {
            TimePickerDialogDefaults.ScrollDisplayModeToggle(
                onDisplayModeChange = {
                    displayMode =
                        if (displayMode == TimePickerDisplayMode.Scroll) {
                            TimePickerDisplayMode.Input
                        } else {
                            TimePickerDisplayMode.Scroll
                        }
                },
                displayMode = displayMode,
            )
        },
    ) {
        if (displayMode == TimePickerDisplayMode.Input) {
            TimeInput(state = state, shapes = TimePickerDefaults.shapes())
        } else {
            TimeScroll(state = state, shapes = TimePickerDefaults.shapes())
        }
    }
}
Parameters
onDismissRequest: () -> Unit

called when the user tries to dismiss the Dialog by clicking outside or pressing the back button. This is not called when the dismiss button is clicked.

confirmButton: @Composable () -> Unit

button which is meant to confirm a proposed action, thus resolving what triggered the dialog. The dialog does not set up any events for this button, nor does it control its enablement, so those need to be set up by the caller.

modifier: Modifier = Modifier

the Modifier to be applied to this dialog's content.

properties: DialogProperties = DialogProperties(usePlatformDefaultWidth = false)

typically platform specific properties to further configure the dialog

modeToggleButton: (@Composable () -> Unit)? = null

Optional toggle to switch between clock and text input modes.

dismissButton: (@Composable () -> Unit)? = null

button which is meant to dismiss the dialog. The dialog does not set up any events for this button so they need to be set up by the caller.

shape: Shape = TimePickerDialogDefaults.richShape

defines the dialog's surface shape as well its shadow

containerColor: Color = TimePickerDialogDefaults.richContainerColor

the color of the dialog's container

content: @Composable ColumnScope.() -> Unit

the content of the dialog (i.e. a TimePicker, for example)