Back to Material Components Android

Date pickers

docs/components/DatePicker.md

1.13.021.8 KB
Original Source
<!--docs: title: "Date pickers" layout: detail section: components excerpt: "Date pickers let users select a date or range of dates." iconId: picker path: /catalog/date-pickers/ -->

Date pickers

Date pickers let users select a date or range of dates.There are three variants of date pickers.

  1. Docked date picker
  2. Modal date picker
  3. Modal date input

Note: Images use various dynamic color schemes.

Design & API documentation

Anatomy

<details> <summary><h4>Docked date picker</h4></summary>
  1. Outlined text field

  2. Menu button: Month selection

  3. Menu button: Year selection

  4. Icon button

  5. Weekdays label text

  6. Unselected date

  7. Today’s date

  8. Outside month date

  9. Text buttons

  10. Container

  11. Outlined text field

  12. Menu button: Month selection (pressed)

  13. Menu button: Year selection (disabled)

  14. Header

  15. Menu

  16. Selected list item

  17. Unselected menu list item

  18. Container

</details> <details> <summary><h4>Modal date picker</h4></summary>
  1. Headline

  2. Supporting text

  3. Header

  4. Container

  5. Icon button

  6. Icon buttons

  7. Weekdays

  8. Today’s date

  9. Unselected date

  10. Text buttons

  11. Selected date

  12. Menu button

  13. Divider

  14. Headline

  15. Supporting text

  16. Header

  17. Container

  18. Icon button

  19. Unselected year

  20. Selected year

  21. Text buttons

  22. Divider

  23. Menu button

  24. Headline

  25. Supporting text

  26. Icon button

  27. Header

  28. Text button

  29. Icon button

  30. Weekdays label text

  31. Container

  32. Unselected date

  33. Today’s date

  34. In range active indicator

  35. In range date

  36. Month subhead

  37. Selected date

  38. Divider

</details> <details> <summary><h4>Modal date input</h4></summary>
  1. Headline
  2. Supporting text
  3. Header
  4. Container
  5. Icon button
  6. Outlined text field
  7. Text buttons
  8. Divider
</details>

More details on anatomy items in the component guidelines.

Key properties

Container

ElementAttributeRelated method(s)Default value
Colorapp:backgroundTintN/A?attr/colorSurfaceContainerHigh
Shapeapp:shapeAppearanceN/A?attr/shapeAppearanceCornerExtraLarge

Title

ElementAttributeRelated method(s)Default value
Styleapp:materialCalendarHeaderTitleN/A@style/Widget.Material3.MaterialCalendar.HeaderTitle
Text labelN/ABuilder.setTitleText
getHeaderTextSelect Date
Colorandroid:textColorN/A?attr/colorOnSurfaceVariant
Typographyandroid:textAppearanceN/A?attr/textAppearanceLabelMedium

Selected date

ElementAttributeRelated method(s)Default value
Styleapp:materialCalendarHeaderSelectionN/A@style/Widget.Material3.MaterialCalendar.HeaderSelection
Colorandroid:textColorN/A?attr/colorOnSurface
Typographyandroid:textAppearanceN/A?attr/textAppearanceHeadlineLarge

Switch-to-keyboard input icon

ElementAttributeRelated method(s)Default value
Styleapp:materialCalendarHeaderToggleButtonN/A@style/Widget.Material3.MaterialCalendar.HeaderToggleButton
Backgroundandroid:backgroundN/A?attr/actionBarItemBackground
Colorandroid:tintN/A?attr/colorOnSurfaceVariant

Year selection menu

ElementAttributeRelated method(s)Default value
Styleapp:materialCalendarYearNavigationButtonN/A@style/Widget.Material3.MaterialCalendar.YearNavigationButton
Text colorandroid:textColorN/A?attr/colorOnSurfaceVariant
Icon colorapp:iconTintN/A?attr/colorOnSurfaceVariant

Month pagination

ElementAttributeRelated method(s)Default value
Styleapp:materialCalendarMonthNavigationButtonN/A@style/Widget.Material3.MaterialCalendar.MonthNavigationButton
Text colorandroid:textColorN/A?attr/colorOnSurfaceVariant
Icon colorapp:iconTintN/A?attr/colorOnSurfaceVariant

Current date

ElementAttributeRelated method(s)Default value
Styleapp:dayTodayStyleN/A@style/Widget.Material3.MaterialCalendar.Day.Today
Text colorapp:itemTextColorN/A?attr/colorPrimary
Stroke colorapp:itemStrokeColorN/A?attr/colorPrimary
Stroke widthapp:itemStrokeWidthN/A1dp

Selected date

ElementAttributeRelated method(s)Default value
Styleapp:daySelectedStyleN/A@style/Widget.Material3.MaterialCalendar.Day.Selected
Background colorapp:itemFillColorN/A?attr/colorPrimary
Text colorapp:itemTextColorN/A?attr/colorOnPrimary
Stroke colorapp:itemStrokeColorN/AN/A
Stroke widthapp:itemStrokeWidthN/A0dp

Selected range

ElementAttributeRelated method(s)Default value
Colorapp:rangeFillColorN/A?attr/colorSurfaceVariant

Cancel button

ElementAttributeRelated method(s)Default value
Styleapp:materialCalendarHeaderCancelButtonN/A@style/Widget.Material3.MaterialCalendar.HeaderCancelButton
Text colorandroid:textColorN/A?attr/colorOnSurface (see all states)
Icon colorapp:iconTintN/A?attr/colorOnSurfaceVariant

Styles and theme overlays

ElementStyle
Default
theme overlayThemeOverlay.Material3.MaterialCalendar
Default styleWidget.Material3.MaterialCalendar
Fullscreen
theme overlayThemeOverlay.Material3.MaterialCalendar.Fullscreen
Full screen styleWidget.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.

Variants of date pickers

<details> <summary><h3>Docked date picker</h3></summary>

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.

Docked date picker example

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:

kt
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()
</details> <details> <summary><h3>Modal date picker</h3></summary>

Modal date pickers navigate across dates in several ways:

  • To navigate across months, swipe horizontally
  • To navigate across years, scroll vertically
  • To access the year picker, tap the year

Date range selection provides a start and end date.

Common use cases include:

  • Booking a flight
  • Reserving a hotel

Modal date pickers navigate across date ranges in several ways:

  • To select a range of dates, tap the start and end dates on the calendar
  • To navigate across months, scroll vertically

Modal date picker example

The following example shows a modal date picker with a date range selected.

In code:

kt
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:

kt
val dateRangePicker =
    MaterialDatePicker.Builder.dateRangePicker()
        .setTitleText("Select dates")
        .setSelection(
          Pair(
            MaterialDatePicker.thisMonthInUtcMilliseconds(),
            MaterialDatePicker.todayInUtcMilliseconds()
          )
        )
        .build()

dateRangePicker.show()
</details> <details> <summary><h3>Modal date input</h3></summary>

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:

kt
val datePickerBuilder =
     MaterialDatePicker.Builder.datePicker()
      .setInputMode(MaterialDatePicker.INPUT_MODE_TEXT)
      datePickerBuilder.setTitleText("Select Date")
      datePickerBuilder.setSelection(MaterialDatePicker.todayInUtcMilliseconds())
val datePicker = datePickerBuilder.build() datePicker.show()
</details>

Code implementation

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.

Date pickers examples

API and source code:

A date range picker can be instantiated with MaterialDatePicker.Builder.dateRangePicker():

kt
val dateRangePicker =
    MaterialDatePicker.Builder.dateRangePicker()
        .setTitleText("Select dates")
        .build()

To set a default selection:

kt
// 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:

kt
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):

kt
MaterialDatePicker.Builder.datePicker()
      ...
    .setDayViewDecorator(CircleIndicatorDecorator())

To show the picker to the user:

kt
picker.show(supportFragmentManager, "tag")

Listen to button clicks, cancel, and dismiss events with the following calls:

kt
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.

Adding calendar constraints

To constrain the calendar from the beginning to the end of this year:

kt
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:

kt
...
calendar[Calendar.MONTH] = Calendar.FEBRUARY
val february = calendar.timeInMillis

val constraintsBuilder =
   CalendarConstraints.Builder()
       .setOpenAt(february)

To set the first day of the week:

kt
val constraintsBuilder =
   CalendarConstraints.Builder()
       .setFirstDayOfWeek(Calendar.MONDAY)

To set a validator:

kt
// 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:

kt
MaterialDatePicker.Builder.datePicker()
      ...
    .setCalendarConstraints(constraintsBuilder.build())

Making date pickers accessible

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:

kt
val picker =
   MaterialDatePicker.Builder.datePicker()
      ...
       .setTitleText("Select appointment date")
   ...

Customizing date pickers

Theming date pickers

Date pickers support the customization of color, typography, and shape.

Date picker theming example

API and source code:

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:

xml
<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:

xml
<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:

kt
val picker =
   MaterialDatePicker.Builder.datePicker()
      ...
       .setTheme(R.style.ThemeOverlay_App_DatePicker)