不幸的是,这不是一项简单的任务。
DatePickers 在内部使用小部件NumberPicker 和CalendarView。例如,您发布的图像使用 3 NumberPickers。您所说的分隔符来自 NumberPicker 的属性:selectionDivider。问题是这个属性不是公开的,numberPickerStyle 也不是,通过它设置这个属性。
我最近将 CalendarView 和 NumberPicker 向后移植到 API 8,主要是为了好玩。由于代码很容易获得(在 android 的源代码中查找 android.widget.NumberPicker 和其他代码),所有这些任务都需要时间,并且需要深入研究 android 的源代码。例子:
-
简单 ==> 您必须将私有变量从 View 类更改为它们的访问器方法
mLeft(View 类中的受保护变量)==> getLeft()(公共访问器方法)
最耗时的任务是恢复辅助功能方法。
无论如何,如果您决定编写 DatePicker 的自定义实现,您还必须为 NumberPicker 和 CalendarView(可选)编写它们。
更简单的方法:
Backported DatePicker 在此处作为库提供:Android-DatePicker。如上所述,您将与此 DatePicker 一起使用向后移植的 CalendarView 和 NumberPicker。
您需要更改的内容:
使用{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>
就是这样。
使用库输出:
编辑:
android:divider 是指日期选择器中的分隔符吗?
我怎么能用它来改变颜色?
属性divider实际上来自LinearLayout。 NumberPicker 继承此属性为 NumberPicker extends LinearLayout。但是这个divider 有不同的用途。传递给此属性的可绘制对象放置在LinearLayout 的子视图之间。
android:showDividers 属性用于更改此分隔线的位置,可能的值是:
- 无:没有显示分隔符
- 开始:分隔线显示在第一个子视图之前
- 中间:分隔线显示在每个子视图之后,而不是在最后一个子视图之后
- 结束:分隔线显示在最后一个子视图之后
android:dividerPadding 属性不言自明。
即使 NumberPicker 继承了这个属性,它也不会使用它。从您自己的研究和试验中可以看出这一点:I tried a multitude of combinations of the two, but I don't seem to get it to work.
查看有效的分隔符属性:
<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 反射的黑客式解决方法:
这个答案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
- 如果您在
sdk/platforms/android-xx/res/layout 中打开date_picker.xml,您会看到三个NumberPicker 的id 为month、day、year。我们访问 android.internal.R.id 以获取这些 NumberPickers 的资源 ID。
- 我们使用这些 id 和
findViewById(int) 方法创建三个 NumberPicker 对象。
- 然后,使用重新选择访问和检索字段
mSelectionDivider。
- 将该字段设置为可访问(作为其声明的最终字段),使用
Field#set(Object, Object) 方法设置其值。第一个参数是我们执行此操作的对象。第二个参数是我们要设置的对象。
我使用的drawable可以从:here下载。