Java Android:如何更改日期选择器分隔符的颜色?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/20148671/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 23:30:39  来源:igfitidea点击:

Android: how to change the color of the datepicker divider?

javaandroidandroid-layoutdatepickerthemes

提问by kramer65

I've got a datepicker in my Android app, but now I want to change the color of the blue dividers into green (see the image below this text). There are someotherdiscussionson Stackoverflow that talk about the same, but none of them gives an answer which leads to a solution.

我的 Android 应用程序中有一个日期选择器,但现在我想将蓝色分隔线的颜色更改为绿色(请参阅本文下方的图片)。在 Stackoverflow 上还有一些其他讨论也讨论了同样的问题,但没有一个给出导致解决方案的答案。

So I went looking myself and found there is actually an android:datePickerStyle and there is also an android:divider. I don't know however, whether the divider is actually referring to the divider in the datepicker at all. I tried a multitude of combinations of the two, but I don't seem to get it to work. So my first question: Does the android:divider refer to the divider in the datepicker, and how could I use it to change color?

所以我自己去找,发现实际上有一个 android:datePickerStyle,还有一个 android:divider。但是,我不知道分隔符是否实际上是指日期选择器中的分隔符。我尝试了两者的多种组合,但我似乎没有让它起作用。所以我的第一个问题是:android:divider 是否指的是 datepicker 中的分隔符,我如何使用它来改变颜色?

So another option is supposedly to create a fully new custom datepicker. If that enables me to just change the color of the divider I'm down for it. So I had a look at someofthetutorialson creating a custom datepicker, but none of them seem to define the color of the dividers. The dividers are simply not listed in the xml files or in the java files.

所以另一个选项应该是创建一个全新的自定义日期选择器。如果这让我能够改变分隔线的颜色,我会为之倾倒。因此,我不得不看看一些教程创建自定义日期选择器,但他们都不来定义分隔的颜色。分隔符根本没有在 xml 文件或 java 文件中列出。

It would be great if there would be some kind of boilerplate code to recreate the datepicker as it currently displays, including the code that sets the color of the dividers. Hopefully that would enable me to copy it and simply change the color setting of the divider somewhere. So my second question: Would anybody know any boilerplate code which simply implements the datepicker as it is now (including a definition of the dividers)?

如果有某种样板代码来重新创建当前显示的日期选择器,包括设置分隔线颜色的代码,那就太好了。希望这能让我复制它并简单地在某处更改分隔线的颜色设置。所以我的第二个问题:有人知道任何简单地实现日期选择器的样板代码吗(包括分隔符的定义)?

enter image description here

在此处输入图片说明

采纳答案by Vikram

Unfortunately, this is not a trivial task.

不幸的是,这不是一项微不足道的任务。

DatePickersuse widgets NumberPickerand CalendarViewinternally. For instance, the image you have posted is using 3 NumberPickers. And the dividers you are talking about come from NumberPicker's attribute: selectionDivider. The problem is that this attribute is not public, and neither is numberPickerStyle, through which, this attribute is set.

DatePickers使用小部件NumberPickerCalendarView内部。例如,您发布的图片使用的是 3 NumberPickers。你所说的分隔符来自 NumberPicker 的属性:selectionDivider。问题是这个属性不是公开的,也不是numberPickerStyle,通过它来设置这个属性。

I recently back-ported CalendarView and NumberPicker to API 8, mostly for fun. Since the code is readily available(look up android.widget.NumberPickerand others in android's source), all this task takes is time, and some digging through android's source-code. Examples:

我最近将 CalendarView 和 NumberPicker 向后移植到 API 8,主要是为了好玩。由于代码随时可用(android.widget.NumberPicker在 android 的源代码中查找和其他代码),所有这些任务都需要时间,以及一些挖掘 android 源代码的工作。例子:

  1. Easy ==> You'll have to change the private variable from View class to their accessor methods

    mLeft (protected variable in View class) ==> getLeft() (public accessor method)

  2. The most time-consuming task was restoring the Accessibility methods.

  1. 简单 ==> 您必须将私有变量从 View 类更改为它们的访问器方法

    mLeft(View 类中的受保护变量)==> getLeft()(公共访问器方法)

  2. 最耗时的任务是恢复辅助功能方法。

In any case, if you do decide on writing custom implementation of DatePicker, you'll have to write them for NumberPicker and CalendarView (optionally) as well.

在任何情况下,如果您决定编写 DatePicker 的自定义实现,您还必须为 NumberPicker 和 CalendarView(可选)编写它们。

Easier way:

更简单的方法:

Backported DatePicker is available as a library here: Android-DatePicker. As mentioned above, you'll be using backported CalendarViewand NumberPickerin conjunction with this DatePicker.

向后移植的 DatePicker 可在此处用作库:Android-DatePicker。如上所述,您将与此 DatePicker 结合使用反向移植的CalendarViewNumberPicker

What you need to change:

你需要改变的:

Use {library-numberpicker} / res / drawable-xxxx / np_numberpicker_selection_divider.9.pngas a template, and change the 'bluish' color to green (I used pixlr). You can either save it with the same name, if you want to be done with the blue divider altogether, or use a different name and make changes in {library-numberpicker} / res / values / themes.xml.

使用{library-numberpicker} / res / drawable-xxxx / np_numberpicker_selection_divider.9.png作为模板,并改变“蓝色”的颜色为绿色(我用的Pixlr)。如果您想完全使用蓝色分隔线,您可以使用相同的名称保存它,或者使用不同的名称并在{library-numberpicker} / res / values / themes.xml.

The changes required in themes.xmlif you choose a different name:

themes.xml如果您选择不同的名称,则所需的更改:

<style name="NPWidget.Holo.NumberPicker" parent="NPWidget.NumberPicker">
    ....
    <item name="selectionDivider">@drawable/new_nine_path_drawable_name</item>
    ....
</style>

And that's it.

就是这样。

Output using the libraries:

使用库输出:

enter image description here

在此处输入图片说明

Edit:

编辑:

Does the android:dividerrefer to the divider in the datepicker, and how could I use it to change color?

是否android:divider指的是日期选择器中的分隔符,我如何使用它来改变颜色?

The attribute divideractually comes from LinearLayout. NumberPickerinherits this attribute as NumberPicker extends LinearLayout. But this dividerserves a different purpose. The drawable passed to this attribute is placed between child views of LinearLayout.

该属性divider实际上来自LinearLayout. NumberPicker将此属性继承为NumberPicker extends LinearLayout. 但这divider有不同的目的。传递给此属性的可绘制对象放置在 的子视图之间LinearLayout

The attribute android:showDividersis used to change the placement of this divider, possible values being:

该属性android:showDividers用于更改此分隔符的位置,可能的值为:

  • none: No dividers shown
  • beginning: Divider is shown before the first child view
  • middle: Divider is shown after each child view, not not after the last child view
  • end: Divider is shown after the last child view
  • none:没有显示分隔线
  • 开始:分隔线显示在第一个子视图之前
  • 中间:分隔线显示在每个子视图之后,而不是在最后一个子视图之后
  • 结束:分隔线显示在最后一个子视图之后

The attribute android:dividerPaddingis self-explanatory.

该属性android:dividerPadding是不言自明的。

Even though NumberPicker inherits this attribute, it does not use it. This is evident from your own research & trials: I tried a multitude of combinations of the two, but I don't seem to get it to work.

即使 NumberPicker 继承了这个属性,它也不使用它。这从您自己的研究和试验中可以明显看出:I tried a multitude of combinations of the two, but I don't seem to get it to work.

To see the divider attribute in action:

要查看操作中的分隔线属性:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="horizontal"
    android:divider="@android:drawable/ic_media_play"
    android:showDividers="middle" >

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="World," />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Again" />

</LinearLayout>

Hack-ish workaround using java reflection:

使用 Java 反射的 Hack-ish 解决方法:

This answer heregave me the idea. I hate using refection in general, mostly for reasons listed in this answer: Link. Although I'm listing it here for completeness sake, I suggestyou don't use it.

这个答案在这里给了我这个想法。我一般讨厌使用反射,主要是出于此答案中列出的原因:链接。虽然我在这里列出它是为了完整起见,但我建议你不要使用它。

public class CDP extends android.widget.DatePicker {

    public CDP(Context context, AttributeSet attrs) {
        super(context, attrs);

        Class<?> internalRID = null;
        try {
            internalRID = Class.forName("com.android.internal.R$id");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }

        Field month = null;
        try {
            month = internalRID.getField("month");
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        }

        NumberPicker npMonth = null;
        try {
            npMonth = (NumberPicker) findViewById(month.getInt(null));
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }

        Field day = null;
        try {
            day = internalRID.getField("day");
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        }

        NumberPicker npDay = null;
        try {
            npDay = (NumberPicker) findViewById(day.getInt(null));
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }

        Field year = null;
        try {
            year = internalRID.getField("year");
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        }

        NumberPicker npYear = null;
        try {
            npYear = (NumberPicker) findViewById(year.getInt(null));
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }

        Class<?> numberPickerClass = null;
        try {
            numberPickerClass = Class.forName("android.widget.NumberPicker");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }

        Field selectionDivider = null;
        try {
            selectionDivider = numberPickerClass.getDeclaredField("mSelectionDivider");
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        }

        try {
            selectionDivider.setAccessible(true);
            selectionDivider.set(npMonth, getResources().getDrawable(
                       R.drawable.np_numberpicker_selection_divider_green));
            selectionDivider.set(npDay, getResources().getDrawable(
                       R.drawable.np_numberpicker_selection_divider_green));
            selectionDivider.set(npYear, getResources().getDrawable(
                       R.drawable.np_numberpicker_selection_divider_green));
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (NotFoundException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
    }
}

What we do here:

我们在这里做什么:

  • Extend DatePicker
  • If you open date_picker.xmlin sdk/platforms/android-xx/res/layout, you'll see that the three NumberPickers have ids month, day, year. We access android.internal.R.idto get resource ids for these NumberPickers.
  • We create three NumberPicker objects using these ids with findViewById(int)method.
  • Then, access and retrieve the Field mSelectionDividerusing relection.
  • Set the field to accessible (as its declared final), set its value using Field#set(Object, Object)method. The first argument is the Object that we perform this operation on. Second argument is the Object that we want to set.
  • 扩展日期选择器
  • 如果你打开date_picker.xmlsdk/platforms/android-xx/res/layout,你会看到这三个NumberPickers有ID monthdayyear。我们可以android.internal.R.id获取这些 NumberPicker 的资源 ID。
  • 我们使用这些 id 和findViewById(int)方法创建了三个 NumberPicker 对象。
  • 然后,使用重选访问和检索字段mSelectionDivider
  • 将字段设置为可访问(作为其声明的最终版本),使用Field#set(Object, Object)方法设置其值。第一个参数是我们执行此操作的对象。第二个参数是我们要设置的对象。

The drawable I have used can be downloaded from: here.

我使用过的 drawable 可以从这里下载。

回答by sumit gupta

From wreckerat Android divider color DatePicker dialog

清障车Android的分隔颜色的DatePicker对话框

You can use these attributes for instance:

<NumberPicker
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            selectionDivider="@color/black" //The divider for making the selection area
            selectionDividerHeight="1px"//The height of the selection divider
            selectionDividersDistance="3dp"//The distance between the two selection dividers
            internalLayout="@layout/something"//The layout of the number picker.
            internalMaxHeight="5dp"//The max height of the NumberPicker (also check other variations)
            internalMinWidth="5dp" // The max width of the NumberPicker (also check other variations)
            virtualButtonPressedDrawable="@drawable/something"//The drawable for pressed virtual (increment/decrement) buttons.
            />

例如,您可以使用这些属性:

<NumberPicker
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            selectionDivider="@color/black" //The divider for making the selection area
            selectionDividerHeight="1px"//The height of the selection divider
            selectionDividersDistance="3dp"//The distance between the two selection dividers
            internalLayout="@layout/something"//The layout of the number picker.
            internalMaxHeight="5dp"//The max height of the NumberPicker (also check other variations)
            internalMinWidth="5dp" // The max width of the NumberPicker (also check other variations)
            virtualButtonPressedDrawable="@drawable/something"//The drawable for pressed virtual (increment/decrement) buttons.
            />

回答by GMan

First of all; Vikram, you did a great job thank you for your effort! One thing I was missing in net.simonvt.datepicker.DatePickerDialogwas the option to set the titleDividercolor which I want to match with numberPickerDividerColor. So I added this option in Vikrams implementation and am posting it here. It's a common solution related to changing AlertDialog.titleDividerColor. Maybe it will help someone.

首先; 维克拉姆,你做得很好,谢谢你的努力!我缺少的一件事是net.simonvt.datepicker.DatePickerDialog设置titleDivider我想要匹配的颜色的选项numberPickerDividerColor。所以我在 Vikrams 实现中添加了这个选项,并在这里发布。这是与更改AlertDialog.titleDividerColor. 也许它会帮助某人。

class net.simonvt.datepicker.DatePickerDialog
private int titleDividerColor;

It's important to set the color when the dialog is shown, so I do this in onAttachedToWindowmethod.

显示对话框时设置颜色很重要,所以我在onAttachedToWindow方法中这样做。

@Override
public void onAttachedToWindow() {
    super.onAttachedToWindow();

    if (titleDividerColor <= 0) { return; }

    try {
        int dividerId = getContext().getResources().getIdentifier("android:id/titleDivider", null, null);
        View divider = findViewById(dividerId);
        if (divider != null) {
            divider.setBackgroundColor(getContext().getResources().getColor(titleDividerColor));
        }
    } catch (Exception e) {}
}

public void setTitleDividerColor(int titleDividerColor) {
    this.titleDividerColor = titleDividerColor;
}

public int getTitleDividerColor() {
    return titleDividerColor;
}

EDIT

编辑

I posted another solution here https://stackoverflow.com/a/33800696/1134335

我在这里发布了另一个解决方案https://stackoverflow.com/a/33800696/1134335

回答by JCLaHoot

I think the simplest solution is probably to use styles.

我认为最简单的解决方案可能是使用样式。

Just put this in your styles.xml document

把它放在你的styles.xml 文件中

    <!-- changes the default colours for EditTexts, including non-text elements (also works with the DatePicker -->

<style name="appCompatStyle" parent="Theme.AppCompat.Light">
    <item name="colorControlNormal">@color/lightPrimaryText</item>
    <item name="colorControlActivated">@color/colorAccent</item>
    <item name="android:editTextStyle">@style/editTextStyle</item>
</style>


<!-- changes the default text colour for the EditTexts -->
<style name="editTextStyle" parent="android:style/Widget.EditText">
    <item name="android:textColor">@color/lightPrimaryText</item>
</style>

and put these attributes in your layout XML

并将这些属性放在您的布局 XML 中

android:theme="@style/appCompatStyle"

and customize it however you like.

并根据您的喜好自定义它。

回答by Wiktor Wardzichowski

For changing just divider color in DatePickerDialog changing android:datePickerDialogTheme style in your theme is sufficient:

对于更改 DatePickerDialog 中的分隔线颜色,更改主题中的 android:datePickerDialogTheme 样式就足够了:

Theme style:

主题风格:

 <style name="BaseTheme" parent="Theme.AppCompat.Light.NoActionBar">
    <item name="android:datePickerDialogTheme">@style/style_date_picker_dialog</item>
</style>

Dialog style:

对话风格:

<style name="style_date_picker_dialog" parent="AppCompatAlertDialogStyle">
<item name="colorControlNormal">@color/colorAccent</item>
</style>

回答by Rajesh Nasit

There is one librarythey have custmize time and date picker. In that you can change color of divider following way

他们有一个库,他们有自定义时间和日期选择器。因为您可以按照以下方式更改分隔线的颜色

    timePicker.setSelectionDivider(new ColorDrawable(0xffff0000));
    timePicker.setSelectionDividerHeight(2);

EditAnother libraryI have also used that is also good one in that you can customize using following way in thems.xml

编辑另一个我也使用过的,它也很好,您可以在 thems.xml 中使用以下方式进行自定义

<style name="NPWidget.Holo.NumberPicker" parent="NPWidget.NumberPicker">
        <item name="solidColor">@android:color/transparent</item>
        <item name="selectionDivider">@color/div_color</item>
        <item name="selectionDividerHeight">0.3dip</item>
        <item name="internalLayout">@layout/number_picker_with_selector_wheel</item>
        <item name="internalMinWidth">64dip</item>
        <item name="internalMaxHeight">140dip</item>
        <item name="virtualButtonPressedDrawable">@drawable/item_background_holo_dark</item>
    </style>

回答by shubham1g5

Setting a theme to DatePickerlayout and adding colorControlNormalto it works for me.

将主题设置为DatePicker布局并添加colorControlNormal到它对我有用。

In your layout's xml add a DatePickerapplying a theme as shown below -

在您的布局的 xml 中添加一个DatePicker应用主题,如下所示 -

<DatePicker xmlns:android="http://schemas.android.com/apk/res/android"
            android:theme="@style/NumberPickerStyle"
            android:datePickerMode="spinner"
            android:calendarViewShown="false"
            android:layout_gravity="center_horizontal"
            android:layout_height="wrap_content"
            android:layout_width="wrap_content"/>

and then define the NumberPickerStylein styles.xmlspecifying colorControlNormallike this -

然后像这样定义NumberPickerStyleinstyles.xml指定colorControlNormal-

<style name="NumberPickerStyle">
        <item name="colorControlNormal">@color/colorAccent</item>
</style>

回答by DNP 92

Change color divider in DatePickerDialogwith android:datePickerMode="spinner"=> Set android:themefor DatePicker

使用android:datePickerMode="spinner"=>为DatePicker设置android:theme更改DatePickerDialog 中的分色器

DatePicker Xml:

日期选择器 Xml:

<DatePicker
        android:id="@+id/datePicker"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:calendarViewShown="false"
        android:theme="@style/MyAppTheme.DatePicker"
        android:datePickerMode="spinner" />

MyAppTheme Xml:

MyAppTheme Xml:

<style name="MyAppTheme.DatePicker" parent="AppTheme">
    <item name="colorControlNormal"> ?colorAccent </item>
</style>

screenshot

截屏