docs/components/DatePicker.md
Date pickers let users select a date or range of dates.There are three variants of date pickers.
Note: Images use various dynamic color schemes.
Outlined text field
Menu button: Month selection
Menu button: Year selection
Icon button
Weekdays label text
Unselected date
Today’s date
Outside month date
Text buttons
Container
Outlined text field
Menu button: Month selection (pressed)
Menu button: Year selection (disabled)
Header
Menu
Selected list item
Unselected menu list item
Container
Headline
Supporting text
Header
Container
Icon button
Icon buttons
Weekdays
Today’s date
Unselected date
Text buttons
Selected date
Menu button
Divider
Headline
Supporting text
Header
Container
Icon button
Unselected year
Selected year
Text buttons
Divider
Menu button
Headline
Supporting text
Icon button
Header
Text button
Icon button
Weekdays label text
Container
Unselected date
Today’s date
In range active indicator
In range date
Month subhead
Selected date
Divider
More details on anatomy items in the component guidelines.
| Element | Attribute | Related method(s) | Default value |
|---|---|---|---|
| Color | app:backgroundTint | N/A | ?attr/colorSurfaceContainerHigh |
| Shape | app:shapeAppearance | N/A | ?attr/shapeAppearanceCornerExtraLarge |
| Element | Attribute | Related method(s) | Default value |
|---|---|---|---|
| Style | app:materialCalendarHeaderTitle | N/A | @style/Widget.Material3.MaterialCalendar.HeaderTitle |
| Text label | N/A | Builder.setTitleText | |
getHeaderText | Select Date | ||
| Color | android:textColor | N/A | ?attr/colorOnSurfaceVariant |
| Typography | android:textAppearance | N/A | ?attr/textAppearanceLabelMedium |
| Element | Attribute | Related method(s) | Default value |
|---|---|---|---|
| Style | app:materialCalendarHeaderSelection | N/A | @style/Widget.Material3.MaterialCalendar.HeaderSelection |
| Color | android:textColor | N/A | ?attr/colorOnSurface |
| Typography | android:textAppearance | N/A | ?attr/textAppearanceHeadlineLarge |
| Element | Attribute | Related method(s) | Default value |
|---|---|---|---|
| Style | app:materialCalendarHeaderToggleButton | N/A | @style/Widget.Material3.MaterialCalendar.HeaderToggleButton |
| Background | android:background | N/A | ?attr/actionBarItemBackground |
| Color | android:tint | N/A | ?attr/colorOnSurfaceVariant |
| Element | Attribute | Related method(s) | Default value |
|---|---|---|---|
| Style | app:materialCalendarYearNavigationButton | N/A | @style/Widget.Material3.MaterialCalendar.YearNavigationButton |
| Text color | android:textColor | N/A | ?attr/colorOnSurfaceVariant |
| Icon color | app:iconTint | N/A | ?attr/colorOnSurfaceVariant |
| Element | Attribute | Related method(s) | Default value |
|---|---|---|---|
| Style | app:materialCalendarMonthNavigationButton | N/A | @style/Widget.Material3.MaterialCalendar.MonthNavigationButton |
| Text color | android:textColor | N/A | ?attr/colorOnSurfaceVariant |
| Icon color | app:iconTint | N/A | ?attr/colorOnSurfaceVariant |
| Element | Attribute | Related method(s) | Default value |
|---|---|---|---|
| Style | app:dayTodayStyle | N/A | @style/Widget.Material3.MaterialCalendar.Day.Today |
| Text color | app:itemTextColor | N/A | ?attr/colorPrimary |
| Stroke color | app:itemStrokeColor | N/A | ?attr/colorPrimary |
| Stroke width | app:itemStrokeWidth | N/A | 1dp |
| Element | Attribute | Related method(s) | Default value |
|---|---|---|---|
| Style | app:daySelectedStyle | N/A | @style/Widget.Material3.MaterialCalendar.Day.Selected |
| Background color | app:itemFillColor | N/A | ?attr/colorPrimary |
| Text color | app:itemTextColor | N/A | ?attr/colorOnPrimary |
| Stroke color | app:itemStrokeColor | N/A | N/A |
| Stroke width | app:itemStrokeWidth | N/A | 0dp |
| Element | Attribute | Related method(s) | Default value |
|---|---|---|---|
| Color | app:rangeFillColor | N/A | ?attr/colorSurfaceVariant |
| Element | Attribute | Related method(s) | Default value |
|---|---|---|---|
| Style | app:materialCalendarHeaderCancelButton | N/A | @style/Widget.Material3.MaterialCalendar.HeaderCancelButton |
| Text color | android:textColor | N/A | ?attr/colorOnSurface (see all states) |
| Icon color | app:iconTint | N/A | ?attr/colorOnSurfaceVariant |
| Element | Style |
|---|---|
| Default | |
| theme overlay | ThemeOverlay.Material3.MaterialCalendar |
| Default style | Widget.Material3.MaterialCalendar |
| Fullscreen | |
| theme overlay | ThemeOverlay.Material3.MaterialCalendar.Fullscreen |
| Full screen style | Widget.Material3.MaterialCalendar.Fullscreen |
Default style theme attribute (set inside the theme overlay):
?attr/materialCalendarStyle
Default theme attribute (set on the app's theme): ?attr/materialCalendarTheme,
?attr/materialCalendarFullscreenTheme (fullscreen)
See the full list of styles, attributes, and theme overlays.
Docked date pickers allow the selection of a specific date and year. The docked date picker displays a date input field by default, and a dropdown calendar appears when the user taps on the input field. Either form of date entry can be interacted with.
Docked date pickers are ideal for navigating dates in both the near future or past and the distant future or past, as they provide multiple ways to select dates.
The following example shows a date picker with a date selected.
In XML:
<com.google.android.material.textfield.textinputlayout
android:id="@+id/booking_date_input_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Select Booking Date"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:endIconMode="custom"
app:endIconDrawable="@drawable/ic_android_black_24dp"
app:endIconContentDescription="Open Date Picker"
style="?attr/textInputOutlinedStyle">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/booking_date_edit_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:focusable="false"
android:clickable="true"
android:inputType="none"
/>
</com.google.android.material.textfield.TextInputLayout>
In code:
val datePickerBuilder.setTitleText("Select Date")
if (bookingDateEditText.text.toString().isNotEmpty()) {
try {
val dateFormat = SimpleDateFormat("dd/MM/yyyy", Locale.getDefault())
dateFormat.timeZone = TimeZone.getTimeZone("UTC")
val parsedDate = dateFormat.parse(bookingDateEditText.text.toString())
parsedDate?.let {
datePickerBuilder.setSelection(it.time)
}
} catch (e: Exception) {
e.printStackTrace()
}
}
val datePicker = datePickerBuilder.build()
datePicker.addOnPositiveButtonClickListener { selection ->
val dateFormat = SimpleDateFormat("dd/MM/yyyy", Locale.getDefault())
dateFormat.timeZone = TimeZone.getTimeZone("UTC")
val formattedDate = dateFormat.format(Date(selection))
bookingDateEditText.setText(formattedDate)
}
datePicker.addOnNegativeButtonClickListener {
bookingDateEditText.clearFocus()
}
datePicker.addOnDismissListener {
bookingDateEditText.clearFocus()
}
datePicker.show()
Modal date pickers navigate across dates in several ways:
Date range selection provides a start and end date.
Common use cases include:
Modal date pickers navigate across date ranges in several ways:
The following example shows a modal date picker with a date range selected.
In code:
val datePicker =
MaterialDatePicker.Builder.datePicker()
.setTitleText("Select date")
.setSelection(MaterialDatePicker.todayInUtcMilliseconds())
.build()
datePicker.show()
The following example shows a modal date range picker with a date range selected.
In code:
val dateRangePicker =
MaterialDatePicker.Builder.dateRangePicker()
.setTitleText("Select dates")
.setSelection(
Pair(
MaterialDatePicker.thisMonthInUtcMilliseconds(),
MaterialDatePicker.todayInUtcMilliseconds()
)
)
.build()
dateRangePicker.show()
Modal date inputs allow the manual entry of dates using the numbers on a keyboard. Users can input a date or a range of dates in a dialog.
In code:
val datePickerBuilder =
MaterialDatePicker.Builder.datePicker()
.setInputMode(MaterialDatePicker.INPUT_MODE_TEXT)
datePickerBuilder.setTitleText("Select Date")
datePickerBuilder.setSelection(MaterialDatePicker.todayInUtcMilliseconds())
val datePicker = datePickerBuilder.build() datePicker.show()
Before you can use Material date pickers, you need to add a dependency to the Material components for Android library. For more information, go to the Getting started page.
Date pickers should be suitable for the context in which they appear and can be embedded into dialogs on mobile devices.
API and source code:
MaterialDatePicker
CalendarConstraints
A date range picker can be instantiated with
MaterialDatePicker.Builder.dateRangePicker():
val dateRangePicker =
MaterialDatePicker.Builder.dateRangePicker()
.setTitleText("Select dates")
.build()
To set a default selection:
// Opens the date picker with today's date selected.
MaterialDatePicker.Builder.datePicker()
...
.setSelection(MaterialDatePicker.todayInUtcMilliseconds())
// Opens the date range picker with the range of the first day of
// the month to today selected.
MaterialDatePicker.Builder.dateRangePicker()
...
.setSelection(
Pair(
MaterialDatePicker.thisMonthInUtcMilliseconds(),
MaterialDatePicker.todayInUtcMilliseconds()
)
)
The picker can be started in text input mode with:
MaterialDatePicker.Builder.datePicker()
...
.setInputMode(MaterialDatePicker.INPUT_MODE_TEXT)
A DayViewDecorator can be set allowing customizing the day of month views
within the picker
(example of a DayViewDecorator):
MaterialDatePicker.Builder.datePicker()
...
.setDayViewDecorator(CircleIndicatorDecorator())
To show the picker to the user:
picker.show(supportFragmentManager, "tag")
Listen to button clicks, cancel, and dismiss events with the following calls:
picker.addOnPositiveButtonClickListener {
// Respond to positive button click.
}
picker.addOnNegativeButtonClickListener {
// Respond to negative button click.
}
picker.addOnCancelListener {
// Respond to cancel events.
}
picker.addOnDismissListener {
// Respond to dismiss events.
}
Finally, you can get the user selection with picker.selection.
To constrain the calendar from the beginning to the end of this year:
val today = MaterialDatePicker.todayInUtcMilliseconds()
val calendar = Calendar.getInstance(TimeZone.getTimeZone("UTC"))
calendar.timeInMillis = today
calendar[Calendar.MONTH] = Calendar.JANUARY
val janThisYear = calendar.timeInMillis
calendar.timeInMillis = today
calendar[Calendar.MONTH] = Calendar.DECEMBER
val decThisYear = calendar.timeInMillis
// Build constraints.
val constraintsBuilder =
CalendarConstraints.Builder()
.setStart(janThisYear)
.setEnd(decThisYear)
To open the picker at a default month:
...
calendar[Calendar.MONTH] = Calendar.FEBRUARY
val february = calendar.timeInMillis
val constraintsBuilder =
CalendarConstraints.Builder()
.setOpenAt(february)
To set the first day of the week:
val constraintsBuilder =
CalendarConstraints.Builder()
.setFirstDayOfWeek(Calendar.MONDAY)
To set a validator:
// Makes only dates from today forward selectable.
val constraintsBuilder =
CalendarConstraints.Builder()
.setValidator(DateValidatorPointForward.now())
// Makes only dates from February forward selectable.
val constraintsBuilder =
CalendarConstraints.Builder()
.setValidator(DateValidatorPointForward.from(february))
You can also use DateValidatorPointBackward or customize by creating a class
that implements DateValidator
(example of a DateValidatorWeekdays
in the MDC catalog).
To set the constraint to the picker's builder:
MaterialDatePicker.Builder.datePicker()
...
.setCalendarConstraints(constraintsBuilder.build())
Material date pickers are fully accessible and compatible with screen readers. The title of your date picker will be read when the user launches the dialog. Use a descriptive title for the task:
val picker =
MaterialDatePicker.Builder.datePicker()
...
.setTitleText("Select appointment date")
...
Date pickers support the customization of color, typography, and shape.
API and source code:
MaterialDatePicker
CalendarConstraints
The following example shows a date picker with Material theming.
Use theme attributes and styles in res/values/styles.xml, which apply to all
date pickers and affect other components:
<style name="Theme.App" parent="Theme.Material3.*">
...
<item name="colorPrimary">@color/shrine_pink_100</item>
<item name="colorOnPrimary">@color/shrine_pink_900</item>
<item name="shapeCornerFamily">cut</item>
</style>
Use a default style theme attribute, styles and a theme overlay which apply to all date pickers but do not affect other components:
<style name="Theme.App" parent="Theme.Material3.*">
...
<item name="materialCalendarTheme">@style/ThemeOverlay.App.DatePicker</item>
</style>
<style name="ThemeOverlay.App.DatePicker" parent="@style/ThemeOverlay.Material3.MaterialCalendar">
<item name="colorPrimary">@color/shrine_pink_100</item>
<item name="colorOnPrimary">@color/shrine_pink_900</item>
<item name="shapeCornerFamily">cut</item>
<!-- Customize text field of the text input mode. -->
<item name="textInputStyle">@style/Widget.App.TextInputLayout</item>
</style>
Set the theme in code, which affects only this date picker:
val picker =
MaterialDatePicker.Builder.datePicker()
...
.setTheme(R.style.ThemeOverlay_App_DatePicker)