androidandroid-stylesandroid-datepickermaterial-components-android

How to style Android MaterialCalendars various components


I'm attempting to style this MaterialCalendar, but I'm not getting anywhere with it, any help would be appreciated. My styles.xml looks similar to the below:

 <style name="AppTheme" parent="Theme.MaterialComponents">
    <item name="materialCalendarTheme">@style/ThemeMaterialCalendar</item>
</style>

<style name="ThemeMaterialCalendar" parent="ThemeOverlay.MaterialComponents.MaterialCalendar">
    <item name="buttonBarPositiveButtonStyle">@style/AlterDialogButtonStyle</item>
    <item name="buttonBarNegativeButtonStyle">@style/AlterDialogButtonStyle</item>
    <item name="materialButtonStyle">@style/ThemeMaterialCalendarTextButton</item>
    <item name="android:colorAccent">@color/accent</item>
</style>

<style name="ThemeMaterialCalendarTextButton" parent="Widget.MaterialComponents.Button.TextButton.Dialog.Flush">
    <item name="android:textColor">?attr/colorAccent</item>
</style>

<style name="AlterDialogButtonStyle" parent="Widget.MaterialComponents.Button.TextButton">
    <item name="android:textColor">?attr/colorAccent</item>
</style>

Which renders something like:

enter image description here

The very light blue/cyan is my colorAccent the header is the purple-y colour. Those are just fine. I was able to change them with the above styles.xml.

However I want to also change the dark grey background of the MaterialCalendar to white, and then of course change the text from white to black or grey (so it can be seen), as well as make the arrows for month and year selection. Any selected year or day should be highlighted with the accent color.

Essentially I want something similar to this (please ignore the fact that the below screen shot is of the old DatePickerDialog and not the new MaterialCalendar):

enter image description here

Any help would be greatly appreciated.

PS: I don't want to change any of my primary, secondary or accent colours for the entire app (as it will ruin the rest of the colour scheme)


Solution

  • The best way to customize the colors in the MaterialDatePicker is to override them:

    <style name="MaterialCalendarThemeBackground" parent="ThemeOverlay.MaterialComponents.MaterialCalendar">
        <item name="colorSurface">@color/....</item>
        <item name="colorOnSurface">@color/....</item>
        <item name="colorPrimary">@color/....</item>      
        <item name="colorOnPrimary">@color/....</item>
    </style>
    

    and then use:

    MaterialDatePicker.Builder<Long> builder = MaterialDatePicker.Builder.datePicker();
    builder.setTheme(R.style.MaterialCalendarThemeBackground);
    

    The background color of the MaterialDatePicker is based on colorSurface attribute.

    <style name="MaterialCalendarThemeBackground" parent="ThemeOverlay.MaterialComponents.MaterialCalendar">
        <item name="colorSurface">@color/....</item>
    </style>
    

    enter image description here

    Instead if you want to change the other colors using a custom style you can do:

        <style name="MaterialCalendarThemeBackground" parent="ThemeOverlay.MaterialComponents.MaterialCalendar">
            <item name="materialCalendarStyle">@style/CustomMaterialCalendar</item>
        </style>
    

    with:

    <style name="CustomMaterialCalendar" parent="Widget.MaterialComponents.MaterialCalendar">
        <item name="dayStyle">@style/CustomWidget_Day</item>
    </style>
    
    <style name="CustomWidget_Day" parent="Widget.MaterialComponents.MaterialCalendar.Day">
        <item name="itemTextColor">@color/...</item>
        <item name="itemStrokeColor">@color/....</item>
    </style>
    
        <style name="CustomMaterialCalendar" parent="Widget.MaterialComponents.MaterialCalendar">
           <item name="daySelectedStyle">@style/CustomSelected</item>
        </style>
    

    with:

      <style name= "CustomSelected" parent="Widget.MaterialComponents.MaterialCalendar.Day.Selected">
        <item name="itemFillColor">...</item>
        <item name="itemTextColor">...</item>
      </style>