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

时间:2013-11-22 15:36:22

标签: java android android-layout datepicker themes

我的Android应用程序中有一个日期选择器,但现在我想将蓝色分隔符的颜色更改为绿色(请参阅本文下方的图像)。 Stackoverflow上有some other discussions,它们都是相同的,但没有一个能给出答案,从而找到解决方案。

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

因此,另一个选择是创建一个全新的自定义日期选择器。如果这让我能够改变分频器的颜色我就失望了。因此,我在创建自定义日期选择器时查看了some of the tutorials,但它们似乎都没有定义分隔符的颜色。分隔符根本没有列在xml文件或java文件中。

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

enter image description here

8 个答案:

答案 0 :(得分:100)

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

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

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

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

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

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

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

    更轻松的方式:

    Backported DatePicker在此处可用作库:Android-DatePicker。如上所述,您将使用反向移植的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>
    

    就是这样。

    使用库输出:

    enter image description here

    修改

      

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

    属性divider实际上来自LinearLayoutNumberPicker将此属性继承为NumberPicker extends LinearLayout。但是这个divider有不同的用途。传递给此属性的drawable放置在LinearLayout的子视图之间。

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

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

    属性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>
    

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

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

    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();
            }
        }
    }
    

    我们在这里做什么:

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

    我使用的drawable可以从以下网址下载:here

答案 1 :(得分:23)

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

将它放在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>

并将这些属性放在布局XML

android:theme="@style/appCompatStyle"

并根据您的喜好自定义。

答案 2 :(得分:3)

他们有一个library来保留时间和日期选择器。您可以按照以下方式更改分隔线的颜色

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

修改 我还使用了另一个library,这也是一个很好的,你可以在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>

答案 3 :(得分:1)

将主题设置为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"/>

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

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

答案 4 :(得分:1)

DatePickerDialog 中使用 android:datePickerMode =“ spinner” =>更改颜色分隔器,为 DatePicker设置 android:theme strong>

DatePicker 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:

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

screenshot

答案 5 :(得分:0)

首先;维克拉姆,你做得很好,谢谢你的努力!我在net.simonvt.datepicker.DatePickerDialog中遗漏的一件事是设置我要与titleDivider匹配的numberPickerDividerColor颜色的选项。所以我在Vikrams实现中添加了这个选项,并在此处发布。这是与更改AlertDialog.titleDividerColor相关的常见解决方案。也许它会帮助别人。

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

在显示对话框时设置颜色很重要,所以我在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;
}

修改

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

答案 6 :(得分:0)

在DatePickerDialog中更改只是分隔符颜色更改主题中的android:datePickerDialogTheme样式就足够了:

主题风格:

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

对话样式:

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

答案 7 :(得分:-4)

来自wreckerAndroid divider color DatePicker dialog

  

您可以使用以下属性:

<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.
            />