更改Android DatePicker对话框的分隔符颜色或主题

时间:2013-06-26 05:50:41

标签: android android-layout styles datepicker

我想改变DatePicker对话框的分隔颜色。

我已经检查了所有重复的问题,但我没有得到任何有用的信息。

我想使用橙色而不是此分色器的蓝色。

现在我的datepicker看起来像这样,我也想删除整个日期选择器的背景。

我将此代码用于datepicker对话框

final Calendar calendarDate = Calendar.getInstance();

DatePickerDialog.OnDateSetListener dateSetListener = new DatePickerDialog.OnDateSetListener() {
        @Override
        public void onDateSet(DatePicker view, int year, int monthOfYear,
                            int dayOfMonth) {
            calendarDate.set(Calendar.YEAR, year);
            calendarDate.set(Calendar.MONTH, monthOfYear);
            calendarDate.set(Calendar.DAY_OF_MONTH, dayOfMonth);
        }
};
DatePickerDialog datePickerDialog = new DatePickerDialog(mContext,
        dateSetListener, calendarDate.get(Calendar.YEAR), calendarDate
                .get(Calendar.MONTH), calendarDate
                .get(Calendar.DAY_OF_MONTH));
datePickerDialog.getDatePicker().setCalendarViewShown(false);
datePickerDialog.show();

Screeshot:

enter image description here

2 个答案:

答案 0 :(得分:2)

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

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

由于代码随时可用(在android的源代码中查找android.widget.NumberPicker和其他代码),所有这些任务都需要时间,有些需要通过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 :(得分:0)

使用自定义样式更改可绘制图像中的分隔颜色/主题,如下所示:

 <?xml version="1.0" encoding="utf-8"?>
   <resources xmlns:android="http://schemas.android.com/apk/res/android">
     <style name="YourTheme" parent="@android:style/Theme">
        <item name="android:divider">@drawable/dialog_divider_color</item>
     </style>
   </resources>

并使用AndroidManifest.xml的{​​{1}}更新android:theme="YourTheme"文件