Search code examples
androidxmlandroid-layoutmaterial-components-androidandroid-datepicker

Android Material Date Range Picker - How to change the text color of only the selected range dates?


I am attempting to reproduce this style with the Material Range Date Picker:

[Calendar date picker with all the selected days in white textColor. The unselected days have a black textColor]2

This is what I have been able to achieve so far:

[Calendar date picker with only the selected boundary days in white textColor. The unselected days have a black textColor and the days within the selected boundaries are in black as well]3

  <style name="MyMaterialCalendarTheme" parent="ThemeOverlay.MaterialComponents.MaterialCalendar">
    <item name="colorOnSurface">@color/black</item>
    <item name="materialCalendarStyle">@style/MyMaterialCalendarStyle</item>
  </style>

  <style name="MyMaterialCalendarStyle"  parent="Widget.MaterialComponents.MaterialCalendar">
    <item name="rangeFillColor">@color/dark_green</item>
    <item name="daySelectedStyle">@style/MyDaySelectedStyle</item>
  </style>

  <style name="MyDaySelectedStyle" parent="Widget.MaterialComponents.MaterialCalendar.Day.Selected">
        <item name="itemTextColor">@color/white</item>
  </style>

Apparently the colorOnSurface attribute sets the textColor for all days in the calendar and daySelectedStyle attribute sets the textColor only for the pair of final and initial days.

Is there a way to make the textColor of days between the start and end date white while keeping the text color of the unselected days black?


Solution

  • Well there is no direct way to do that. But you can edit the source code to achieve this.

    daySelectedStyle attribute sets the textColor only for the pair of final and initial days.

    If you see the source code of RangeDateSelector, you can see that the getSelectedDays() method only adds the start and end date.

    RangeDateSelector

    You can change the logic to include all the dates between the two selected dates.

    For example, you can add this code in between the two if statements :

    if (selectedStartItem != null && selectedEndItem != null) {
      Long l = selectedStartItem + 86401000;
      for (; l < selectedEndItem;) {
        selections.add(l);
        l = l + 86401000;
      }
    }
    

    The function will look like this :

    VScode

    The coloring part is executed in the MonthAdapter.java

    Final Result :

    ScreenShot