如何在Android 5.0中更改DatePicker对话框的颜色

123

有可能更改Android 5.0的日期选择器(和时间选择器)的颜色方案吗?

我已尝试设置强调颜色,但这并不起作用(无论是否使用android):

<!-- colorPrimary is used for the default action bar background -->
<item name="colorPrimary">@color/purple</item>

<!-- colorPrimaryDark is used for the status bar -->
<item name="colorPrimaryDark">@color/purple_tint</item>

<!-- colorAccent is used as the default value for colorControlActivated
     which is used to tint widgets -->
<item name="colorAccent">@color/purple_tint</item>

来自原始:

Original

转换为类似以下内容:

Recolored


你的应用程序主题样式中的颜色强调集设置为什么颜色? - the-ginger-geek
@Neil,我已经添加了到目前为止我尝试使用的样式代码。 - Warpzit
10个回答

352
Neil的建议能够实现全屏DatePicker的原因是因为父主题的选择:
<!-- Theme.AppCompat.Light is not a dialog theme -->
<style name="DialogTheme" parent="**Theme.AppCompat.Light**">
    <item name="colorAccent">@color/blue_500</item>
</style>

此外,如果您选择该路线,则必须在创建DatePickerDialog时指定主题:

// R.style.DialogTheme
new DatePickerDialog(MainActivity.this, R.style.DialogTheme, new DatePickerDialog.OnDateSetListener() {
    @Override
    public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) {
        //DO SOMETHING
    }
}, 2015, 02, 26).show();

依我之见,这并不好。应该尽量将样式放在styles.xml/themes.xml内而非Java代码中。

我同意Neil的建议,在稍微修改一下(比如把父主题改为Theme.Material.Light.Dialog)后你就可以得到想要的结果。但是,这里有另外一种方式:

首先考虑到datePickerStyle属性,其中定义了一些东西,例如: headerBackground(你想要更改的内容),dayOfWeekBackground和一些其他的文字颜色和文字样式。

在你应用程序的主题中覆盖此属性将不起作用。DatePickerDialog使用一个单独的主题,可以通过属性datePickerDialogTheme进行分配。因此,为了使我们的更改生效,我们必须在重载的datePickerDialogTheme中覆盖datePickerStyle

现在开始操作:

在你应用程序的基本主题中覆盖datePickerDialogTheme

<style name="AppBaseTheme" parent="android:Theme.Material.Light">
    ....
    <item name="android:datePickerDialogTheme">@style/MyDatePickerDialogTheme</item>
</style>

定义MyDatePickerDialogTheme。父主题的选择取决于您的应用程序基本主题是什么:它可以是Theme.Material.DialogTheme.Material.Light.Dialog中的任何一个:

<style name="MyDatePickerDialogTheme" parent="android:Theme.Material.Light.Dialog">
    <item name="android:datePickerStyle">@style/MyDatePickerStyle</item>
</style>

我们已经用样式MyDatePickerStyle覆盖了datePickerStyle。选择父类将再次取决于您的应用程序基础主题: Widget.Material.DatePickerWidget.Material.Light.DatePicker。根据您的要求定义它:

<style name="MyDatePickerStyle" parent="@android:style/Widget.Material.Light.DatePicker">
    <item name="android:headerBackground">@color/chosen_header_bg_color</item>
</style>

目前,我们只覆盖了headerBackground,默认情况下它被设置为?attr/colorAccent(这也是为什么Neil建议在更改背景时有效的原因)。但是有很多自定义选项:

dayOfWeekBackground
dayOfWeekTextAppearance
headerMonthTextAppearance
headerDayOfMonthTextAppearance
headerYearTextAppearance
headerSelectedTextColor
yearListItemTextAppearance
yearListSelectorColor
calendarTextColor
calendarSelectedTextColor

如果您不希望过多的控制(定制),则无需覆盖datePickerStylecolorAccent 控制大多数 DatePicker 的颜色。因此,在 MyDatePickerDialogTheme 中仅覆盖 colorAccent 应该就可以了:

<style name="MyDatePickerDialogTheme" parent="android:Theme.Material.Light.Dialog">
    <item name="android:colorAccent">@color/date_picker_accent</item>

    <!-- No need to override 'datePickerStyle' -->
    <!-- <item name="android:datePickerStyle">@style/MyDatePickerStyle</item> -->
</style>

覆盖 colorAccent 属性可以使 OKCANCEL 文字的颜色也一并改变,不错。

这样你就不需要在 DatePickerDialog 的构造函数中提供任何样式信息了。一切都已经正确地连接好了:

DatePickerDialog dpd = new DatePickerDialog(this, new DatePickerDialog.OnDateSetListener() {
    @Override
    public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) {

    }
 }, 2015, 5, 22);

 dpd.show();

10
感谢您提供了一个详细的描述,说明它是如何工作的以及在样式中如何被覆盖。 - Warpzit
1
@Vikram未找到calendarSelectedTextColor。 - Akhilesh Dhar Dubey
7
Android的DatePicker组件是否支持向后兼容到版本小于21的设备? - RoCkDevstack
1
@RoCk 不太确定你的意思,但我建立了一个库,将 Android 版本 23 的日期和时间选择器向后移植到版本 14。该项目托管在:https://github.com/vikramkakkar/SublimePicker。 - Vikram
1
太棒了!我只想补充一点,我发现 android:colorAccent 显然不包括选择圆圈的颜色,但是纯粹的 colorAccent 将覆盖 两个 选择颜色和“确定”/“取消”按钮文本。 (或者您可以使用两者来使用不同的颜色!)这是使用 AndroidX Material 1.1.0 库,并且可能会因 DatePicker 的不同版本而有所不同。 - big_m
显示剩余7条评论

72

试一试吧。

代码

new DatePickerDialog(MainActivity.this, R.style.DialogTheme, new DatePickerDialog.OnDateSetListener() {
    @Override
    public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) {
        //DO SOMETHING
    }
}, 2015, 02, 26).show();

样式在styles.xml文件中

编辑- 根据建议更改主题为Theme.AppCompat.Light.Dialog

<style name="DialogTheme" parent="Theme.AppCompat.Light.Dialog">
    <item name="colorAccent">@color/blue_500</item>
</style>

2
是的,它是紫色的,但也是全屏的 :) 但也许如果我把它放到一个片段中,它就会被包含在内了。在我再次尝试之前,有什么建议吗? - Warpzit
我会看看是否能找到更合适的解决方案,不会导致其全屏。 - the-ginger-geek
11
请使用parent="Theme.AppCompat.Light.Dialog"代替parent="Theme.AppCompat.Light" - Chupik
@Neil 谢谢你的回答,指点了我正确的方向,这可能是最快的解决方案,但我正在寻找一种全面的样式/主题方法 :) - Warpzit
无法在Android 6上运行,它是全屏的,颜色没有改变。 - Jemshit Iskenderov

27
创建新样式。
<!-- Theme.AppCompat.Light.Dialog -->
<style name="DialogTheme" parent="Theme.AppCompat.Light.Dialog">
    <item name="colorAccent">@color/blue_500</item>
</style>

Java代码:

关键在于父主题。选择你的colorAccent。

DatePickerDialog = new DatePickerDialog(context,R.style.DialogTheme,this,now.get(Calendar.YEAR),now.get(Calendar.MONTH),now.get(Calendar.DAY_OF_MONTH);

结果:

在此输入图片描述


9

尝试一下这个,对我有用

将两个选项colorAccentandroid:colorAccent放在一起

<style name="AppTheme" parent="@style/Theme.AppCompat.Light.NoActionBar">
    <!-- Customize your theme here. -->
   ....
    <item name="android:dialogTheme">@style/AppTheme.DialogTheme</item>
    <item name="android:datePickerDialogTheme">@style/Dialog.Theme</item>
</style>

<style name="AppTheme.DialogTheme" parent="Theme.AppCompat.Light.Dialog">

<!-- Put the two options, colorAccent and android:colorAccent. -->
    <item name="colorAccent">@color/colorPrimary</item>
    <item name="android:colorPrimary">@color/colorPrimary</item>
    <item name="android:colorPrimaryDark">@color/colorPrimaryDark</item>
    <item name="android:colorAccent">@color/colorPrimary</item>
 </style>

这个答案不需要 v24 及以上的 API。 - Michael

3

值得一提的是,您也可以使用默认的主题,例如android.R.style.Theme_DeviceDefault_Light_Dialog

new DatePickerDialog(MainActivity.this, android.R.style.Theme_DeviceDefault_Light_Dialog, new DatePickerDialog.OnDateSetListener() {
@Override
public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) {
    //DO SOMETHING
    }
}, 2015, 02, 26).show();

1
<style name="AppThemeDatePicker" parent="Theme.AppCompat.Light.NoActionBar">
    <item name="colorAccent">@color/select2</item>
    <item name="android:colorAccent">@color/select2</item>
    <item name="android:datePickerStyle">@style/MyDatePickerStyle</item>
</style>


<style name="MyDatePickerStyle" parent="@android:style/Widget.Material.Light.DatePicker">
    <item name="android:headerBackground">@color/select2</item>
</style>

1

就像宝石一样好用,兄弟! - vss
AlertDialog.THEME_HOLO_LIGHT已经过时,不再起作用。 - Yash

1

我遇到一个问题,即在 Android 的 API 24 上,时间选择器按钮没有显示在屏幕上。(API 21+) 这个问题已经被解决了。

<style name="MyDatePickerDialogTheme" parent="android:Theme.Material.Light.Dialog">
            <item name="android:colorAccent">@color/colorPrimary2</item></style>

<style name="Theme" parent="BBaseTheme">
         <item name="android:datePickerDialogTheme">@style/MyDatePickerDialogTheme</item>
</style>

0

更改年份列表项文本颜色(适用于Android 5.0特定)

只需在您的日期选择器对话框样式中设置特定的文本颜色即可。由于某种原因,设置标志yearListItemTextAppearance不会反映年份列表上的任何更改。

<item name="android:textColor">@android:color/black</item>

0

Kotlin,2021年

// set date as button text if pressed
btnDate.setOnClickListener(View.OnClickListener {

    val dpd = DatePickerDialog(
        this,
        { view, year, monthOfYear, dayOfMonth ->
            val selectDate = Calendar.getInstance()
            selectDate.set(Calendar.YEAR, year)
            selectDate.set(Calendar.MONTH, monthOfYear)
            selectDate.set(Calendar.DAY_OF_MONTH, dayOfMonth)

            var formatDate = SimpleDateFormat("dd/MM/yyyy", Locale.getDefault())
            val date = formatDate.format(selectDate.time)
            Toast.makeText(this, date, Toast.LENGTH_SHORT).show()
            btnDate.text = date
        }, 1990, 6, 6
    )

    val calendar = Calendar.getInstance()
    val year = calendar[Calendar.YEAR]
    val month = calendar[Calendar.MONTH]
    val day = calendar[Calendar.DAY_OF_MONTH]
    dpd.datePicker.minDate = GregorianCalendar(year - 90, month, day, 0, 0).timeInMillis
    dpd.datePicker.maxDate = GregorianCalendar(year - 10, month, day, 0, 0).timeInMillis
    dpd.show()
})

Styles.xml

<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
    <!-- This is main Theme Style for your application! -->
    <item name="android:datePickerDialogTheme">@style/MyDatePickerDialogTheme</item>
</style>

<style name="MyDatePickerDialogTheme" parent="android:Theme.Material.Dialog">
    <item name="android:datePickerStyle">@style/MyDatePickerStyle</item>
</style>

<style name="MyDatePickerStyle" parent="@android:style/Widget.Material.DatePicker">
    <item name="android:headerBackground">#A500FF</item>
</style>

enter image description here


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接