Material 3 Date Pickers in Jetpack Compose

Material 3 Date Pickers in Jetpack Compose

Get started with Material 3 date pickers in Jetpack Compose to create user-friendly interfaces for selecting single dates or date ranges.

Explore Date Picker Styles

Learn to implement three Material 3 date picker types for date selection.

There are three Date Picker styles:
  1. Docked
  2. Modal
  3. Modal Input

Docked Date Picker

Displays an inline date picker below a text field for compact layouts.


@Composable
fun DatePickerDocked() {
    var showDatePicker by remember { mutableStateOf(false) }
    val datePickerState = rememberDatePickerState()
    val selectedDate = datePickerState.selectedDateMillis?.let {
        convertMillisToDate(it)
    } ?: ""
    Box(
        modifier = Modifier.fillMaxWidth()
    ) {
        OutlinedTextField(
            value = selectedDate,
            onValueChange = { },
            label = { Text("DOB") },
            readOnly = true,
            trailingIcon = {
                IconButton(onClick = { showDatePicker = !showDatePicker }) {
                    Icon(
                        imageVector = Icons.Default.DateRange,
                        contentDescription = "Select date"
                    )
                }
            },
            modifier = Modifier
                .fillMaxWidth()
                .height(64.dp)
        )
        if (showDatePicker) {
            Popup(
                onDismissRequest = { showDatePicker = false },
                alignment = Alignment.TopStart
            ) {
                Box(
                    modifier = Modifier
                        .fillMaxWidth()
                        .offset(y = 64.dp)
                        .shadow(elevation = 4.dp)
                        .background(MaterialTheme.colorScheme.surface)
                        .padding(16.dp)
                ) {
                    DatePicker(
                        state = datePickerState,
                        showModeToggle = false
                    )
                }
            }
        }
    }
}
fun convertMillisToDate(millis: Long): String {
    val formatter = SimpleDateFormat("MM/dd/yyyy", Locale.getDefault())
    return formatter.format(Date(millis))
}
  

Use a Docked Date Picker when you want to integrate date selection in compact layouts.

Examples:

  • Select a date in a form
  • Pick a birthday in a profile
  • Choose a date in a booking app

Modal Date Picker

Displays a dialog overlay for focused date selection.


@Composable
fun DatePickerModal(
    onDateSelected: (Long?) -> Unit,
    onDismiss: () -> Unit
) {
    val datePickerState = rememberDatePickerState()
    DatePickerDialog(
        onDismissRequest = onDismiss,
        confirmButton = {
            TextButton(onClick = {
                onDateSelected(datePickerState.selectedDateMillis)
                onDismiss()
            }) {
                Text("OK")
            }
        },
        dismissButton = {
            TextButton(onClick = onDismiss) {
                Text("Cancel")
            }
        }
    ) {
        DatePicker(state = datePickerState)
    }
}
  

Use a Modal Date Picker when you want to focus on date selection with a dialog.

Examples:

  • Choose a date in a calendar app
  • Select a delivery date
  • Pick an event date

Modal Input Date Picker

Combines a text field with a modal dialog for date input.


@Composable
fun DatePickerModalInput(
    onDateSelected: (Long?) -> Unit,
    onDismiss: () -> Unit
) {
    val datePickerState = rememberDatePickerState(initialDisplayMode = DisplayMode.Input)
    DatePickerDialog(
        onDismissRequest = onDismiss,
        confirmButton = {
            TextButton(onClick = {
                onDateSelected(datePickerState.selectedDateMillis)
                onDismiss()
            }) {
                Text("OK")
            }
        },
        dismissButton = {
            TextButton(onClick = onDismiss) {
                Text("Cancel")
            }
        }
    ) {
        DatePicker(state = datePickerState)
    }
}
  

Use a Modal Input Date Picker when you want to combine text input with a dialog.

Examples:

  • Enter a date in a travel app
  • Input a due date in a task app
  • Select a date in a form

Date Range Picker

Allows selection of a start and end date range in a modal dialog.


@Composable
fun DateRangePickerModal(
    onDateRangeSelected: (Pair) -> Unit,
    onDismiss: () -> Unit
) {
    val dateRangePickerState = rememberDateRangePickerState()
    DatePickerDialog(
        onDismissRequest = onDismiss,
        confirmButton = {
            TextButton(
                onClick = {
                    onDateRangeSelected(
                        Pair(
                            dateRangePickerState.selectedStartDateMillis,
                            dateRangePickerState.selectedEndDateMillis
                        )
                    )
                    onDismiss()
                }
            ) {
                Text("OK")
            }
        },
        dismissButton = {
            TextButton(onClick = onDismiss) {
                Text("Cancel")
            }
        }
    ) {
        DateRangePicker(
            state = dateRangePickerState,
            title = { Text("Select date range") },
            showModeToggle = false,
            modifier = Modifier
                .fillMaxWidth()
                .height(500.dp)
                .padding(16.dp)
        )
    }
}
  

Use a Date Range Picker when you want to select a start and end date.

Examples:

  • Choose a vacation period
  • Select a date range for reports
  • Pick a booking range

Date Picker Properties

Understand the key properties used in the date picker examples.

Property Usage
state* Required: DatePickerState or DateRangePickerState for tracking selections
onDismissRequest Handles dialog dismissal
confirmButton Confirms date selection in dialog
dismissButton Cancels dialog without saving
initialDisplayMode Sets initial mode to Input for Modal Input Date Picker
showModeToggle Enables/disables mode toggle in DatePicker

Post a Comment

Previous Post Next Post