Android:如何更改datepicker分隔符的颜色?

kra*_*r65 36 java android themes datepicker android-layout

我的Android应用程序中有一个日期选择器,但现在我想将蓝色分隔符的颜色更改为绿色(请参阅本文下方的图像).Stackoverflow上还有其他一些 讨论相同的讨论,但没有一个讨论会给出解决方案.

所以我去看自己,发现实际上有一个android:datePickerStyle,还有一个android:divider.然而,我不知道分频器是否实际上是指日期选择器中的分频器.我尝试了两者的多种组合,但我似乎没有让它发挥作用.所以我的第一个问题:android:divider是否引用了datepicker中的分隔符,我怎么能用它来改变颜色?

因此,另一个选择应该是创建一个全新的自定义日期选择器.如果这让我能够改变分频器的颜色我就失望了.因此,我不得不看看一些 教程创建自定义日期选择器,但他们都不来定义分隔的颜色.分隔符根本没有列在xml文件或java文件中.

如果会有某种样板代码重新创建当前显示的日期选择器,包括设置分隔符颜色的代码,那将会很棒.希望这能让我复制它,只需更改分隔符的颜色设置.所以我的第二个问题:是否有人知道任何样板代码,它只是现在实现了datepicker(包括分隔符的定义)?

在此输入图像描述

Vik*_*ram 100

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

DatePickers使用小部件NumberPickerCalendarView内部.例如,您发布的图片使用的是3 NumberPickers.你所谈论的分频器来自NumberPicker的属性:selectionDivider.问题是该属性不是公共的,也不是numberPickerStyle通过该属性设置的.

我最近将CalendarView和NumberPicker后端移植到API 8,主要是为了好玩.由于代码很容易获得(android.widget.NumberPicker在Android的源代码中查找和其他代码),所有这些任务都需要时间,有些需要通过android的源代码进行挖掘.例子:

  1. Easy ==>您必须将私有变量从View类更改为其访问器方法

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

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

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

更简单的方法:

Backported DatePicker在这里作为库提供:Android-DatePicker.如上所述,您将使用backported CalendarViewNumberPicker与此DatePicker结合使用.

你需要改变什么:

使用{library-numberpicker} / res / drawable-xxxx / np_numberpicker_selection_divider.9.png作为模板,并改变"蓝色"的颜色为绿色(我用的Pixlr).您可以使用相同的名称保存它,如果您想完全使用蓝色分隔符,或使用其他名称并进行更改{library-numberpicker} / res / values / themes.xml.

themes.xml如果您选择其他名称,则需要进行更改:

<style name="NPWidget.Holo.NumberPicker" parent="NPWidget.NumberPicker">
    ....
    <item name="selectionDivider">@drawable/new_nine_path_drawable_name</item>
    ....
</style>
Run Code Online (Sandbox Code Playgroud)

就是这样.

使用库输出:

在此输入图像描述

编辑:

是否android:divider引用了datepicker中的分隔符,我怎么能用它来改变颜色?

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

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

  • none:没有显示分隔线
  • 开头:分隔符显示在第一个子视图之前
  • middle:分隔符显示在每个子视图之后,而不是在最后一个子视图之后
  • 结束:分隔符显示在最后一个子视图之后

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

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

要查看操作中的divider属性:

<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>
Run Code Online (Sandbox Code Playgroud)

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

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

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();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我们在这里做什么:

  • 扩展DatePicker
  • 如果你打开date_picker.xmlsdk/platforms/android-xx/res/layout,你会看到这三个NumberPickers有ID month,day,year.我们访问android.internal.R.id以获取这些NumberPickers的资源ID.
  • 我们使用这些ID和findViewById(int)方法创建三个NumberPicker对象.
  • 然后,mSelectionDivider使用relection 访问和检索Field .
  • 将字段设置为accessible(如其声明的final),使用Field#set(Object, Object)method 设置其值.第一个参数是我们执行此操作的Object.第二个参数是我们想要设置的Object.

我已经使用了绘制可以从以下网址下载:在这里.


JCL*_*oot 24

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

只需将它放在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>
Run Code Online (Sandbox Code Playgroud)

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

android:theme="@style/appCompatStyle"
Run Code Online (Sandbox Code Playgroud)

并根据自己的喜好自定义它.

  • 在Android 4.3和4.4不工作,在Android 5及更高版本 - 工作得很好 (3认同)
  • 这不会改变 API 21 的分隔线颜色 (2认同)

小智 8

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

日期选择器 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" />
Run Code Online (Sandbox Code Playgroud)

我的应用程序主题 XML:

<style name="MyAppTheme.DatePicker" parent="AppTheme">
    <item name="colorControlNormal"> ?colorAccent </item>
</style>
Run Code Online (Sandbox Code Playgroud)

截屏


shu*_*1g5 6

DatePicker布局设置主题并添加主题colorControlNormal对我来说很有效。

在布局的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"/>
Run Code Online (Sandbox Code Playgroud)

然后NumberPickerStyle在这样styles.xml指定中定义colorControlNormal-

<style name="NumberPickerStyle">
        <item name="colorControlNormal">@color/colorAccent</item>
</style>
Run Code Online (Sandbox Code Playgroud)


归档时间:

查看次数:

57266 次

最近记录:

7 年,5 月 前