Styling CalendarDatePicker

Viewed 571

I am trying to style CalendarDatePicker to a specific color palette. I have been able to style all portions of the CalendarDatePicker to the correct color palette except for the header. All the websites and StackOverflow responses say this should work:

<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools">
    <style name="Widget.Foo.CalendarDatePicker" parent="@android:style/Widget.DatePicker">
        <item name="android:datePickerMode">calendar</item>
    </style>

    <style name="Widget.Foo.CalendarDatePickerDialog" parent="@style/ThemeOverlay.MaterialComponents.MaterialCalendar">
        <item name="buttonBarPositiveButtonStyle">@style/Buttons</item>
        <item name="buttonBarNegativeButtonStyle">@style/Buttons</item>
        <item name="android:textColorPrimary">@color/white</item>
        <item name="materialCalendarHeaderLayout">@style/CustomHeaderLayout</item>
        <item name="colorPrimary">@color/android_purple</item>
        <item name="colorAccent">@color/android_purple</item>
        <item name="colorSurface">@color/black</item>
    </style>

    <style name="Buttons" parent="Widget.MaterialComponents.Button.TextButton">
        <item name="android:textColor">@color/android_purple</item>
    </style>

    <style name="CustomHeaderLayout" parent="Widget.MaterialComponents.MaterialCalendar.HeaderLayout">
        <item name="android:background">@color/android_purple</item>
    </style>

however, the section:

<style name="CustomHeaderLayout" parent="Widget.MaterialComponents.MaterialCalendar.HeaderLayout">
        <item name="android:background">@color/android_purple</item>
    </style>

is not setting the calendar header background purple, it is staying grey (see attached)enter image description here

Is there a different item name value that I should be using?

1 Answers

To change the header background color you have to use the <item name="colorAccent">. Below are three different xml styles to customise the DatePickerDialog.

Option 1 - @style/ThemeOverlay.MaterialComponents.MaterialCalendar

<style name="MaterialCalendarCustomStyle" parent="@style/ThemeOverlay.MaterialComponents.MaterialCalendar">
    <!-- Buttons Color-->
    <item name="colorPrimary">@android:color/holo_purple</item>
    <!--Days unselected Text Color and Month Text Color-->
    <item name="android:textColorPrimary">@android:color/holo_red_light</item>
    <!--Header Background Color and selected Day Background Color-->
    <item name="colorAccent">@android:color/holo_green_dark</item>
    <!--Month Background Color-->
    <item name="colorSurface">@android:color/black</item>
</style>

Option 2 - @style/Theme.AppCompat.Light.Dialog

<style name="DatePickerDialogAppCompatStyle" parent="Theme.AppCompat.Light.Dialog">
    <!--Header Background Color and selected Day Background Color-->
    <item name="colorAccent">@android:color/holo_green_dark</item>
    <item name="android:colorAccent">@android:color/holo_green_dark</item>
    <!--Days unselected Text Color and Month Text Color-->
    <item name="android:textColorPrimary">@android:color/holo_red_light</item>
    <!--Picker Background Color-->
    <item name="android:windowBackground">@android:color/black</item>
    <!--Buttons Style (Text Color & backgroundTint)-->
    <item name="android:buttonBarButtonStyle">@style/MyButtonBarButtonStyle</item>
</style>

<style name="MyButtonBarButtonStyle">
    <item name="android:textColor">@android:color/holo_purple</item>
    <item name="backgroundTint">@android:color/transparent</item>
</style>

Option 3 - @style/android:Theme.Material.Light.Dialog

<style name="DatePickerDialogMaterialStyle" parent="android:Theme.Material.Light.Dialog">
    <!--Header Background Color and selected Day Background Color-->
    <item name="colorAccent">@android:color/holo_green_dark</item>
    <item name="android:colorAccent">@android:color/holo_green_dark</item>
    <!--Days unselected Text Color and Month Text Color-->
    <item name="android:textColorPrimary">@android:color/holo_red_light</item>
    <!--Picker Background Color-->
    <item name="android:windowBackground">@android:color/black</item>
    <!--Buttons Style (Text Color & backgroundTint)-->
    <item name="android:buttonBarButtonStyle">@style/MyButtonBarButtonStyle</item>
</style>

<style name="MyButtonBarButtonStyle">
    <item name="android:textColor">@android:color/holo_purple</item>
    <item name="backgroundTint">@android:color/transparent</item>
</style>

And use any of the above styles programmatically like in the below example:

DatePickerDialog(this, R.style.MaterialCalendarCustomStyle, { view, year, monthOfYear, dayOfMonth -> }, 2021, 11, 20).show()

or in Xml Layout like below:

<DatePicker
    android:theme="@style/MaterialCalendarCustomStyle"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:background="@android:color/black"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintTop_toTopOf="parent"
    app:layout_constraintBottom_toBottomOf="parent"/>

Programmatically

In case you want to change the header color programmatically make a subclass of DatePickerDialog and change the header background color like below:

class MyDatePickerDialog : DatePickerDialog {

    @RequiresApi(api = Build.VERSION_CODES.N)
    constructor(context: Context) : super(context) {
        init(context)
    }

    @RequiresApi(api = Build.VERSION_CODES.N)
    constructor(context: Context, themeResId: Int) : super(context, themeResId) {
        init(context)
    }

    constructor(context: Context, @Nullable listener: OnDateSetListener?, year: Int, month: Int, dayOfMonth: Int) : super(context, listener, year, month, dayOfMonth) {
        init(context)
    }

    constructor(context: Context, themeResId: Int, @Nullable listener: OnDateSetListener?, year: Int, monthOfYear: Int, dayOfMonth: Int) : super(context, themeResId, listener, year, monthOfYear, dayOfMonth) {
        init(context)
    }

    private fun init(context: Context) {
        //find programmatically the android:id/date_picker_header View and change the Header Background Color
        val headerView: ViewGroup? = datePicker.findViewById(context.getResources().getIdentifier("android:id/date_picker_header", "id", context.getPackageName()))
        headerView?.setBackgroundColor(ContextCompat.getColor(context, android.R.color.holo_purple))
    }
}

and use the above subclass like below:

MyDatePickerDialog(this, R.style.MaterialCalendarCustomStyle, null, 2021, 11, 20 ).show()

Result:

date_picker

Related