android日期选择控件DatePickerDialog-2.3版本如何使用holo风格

使用DatePickerDialog:

final Calendar c = Calendar.getInstance();
int mYear = c.get(Calendar.YEAR);
int mMonth = c.get(Calendar.MONTH);
int mDay = c.get(Calendar.DAY_OF_MONTH);
new DatePickerDialog(DialogSample.this,
                mDateSetListener,
                mYear, mMonth, mDay).show();

上面的代码展示了如何显示一个日期选择控件(注意仅仅是显示)。更详细的使用方法这里就不讨论了,这篇文章主要是研究它的外观。
自从ics之后DatePickerDialog在不同的主题下有不同的外观,如果你的主题不是holo风格,那么DatePickerDialog的样式如下:

而如果你的主题是holo风格,在代码相同的情况下又是这样:

不管从外观还是交互上,holo风格下的DatePickerDialog都要好很多,其实这完全就是两个迥异的dialog。

为什么在不同的主题下会完全不同呢?holo最多在颜色上更扁平化而已,一般不会影响到控件的功能,但是两个dialog中一个是通过点击来改变日期,一个是通过滑动来改变日期。那么造成这个结果的原因是什么呢?

一开始猜想是在DatePickerDialog的初始化中判断了主题,然后调用了不同的DatePicker,仔细研究了DatePickerDialog的源码,发现自己错了,其实关键因素是选择日期的NumberPicker控件,这个控件在holo下所用的布局跟非holo不同。

NumberPicker的代码注释中是这样说的:

  • If the current theme is derived from {@link android.R.style#Theme} the widget

  • presents the current value as an editable input field with an increment button

  • above and a decrement button below.

  • If the current theme is derived from {@link android.R.style#Theme_Holo} or

  • {@link android.R.style#Theme_Holo_Light} the widget presents the current

  • value as an editable input field with a lesser value above and a greater

  • value below. Tapping on the lesser or greater value selects it by animating

  • the number axis up or down to make the chosen value current. Flinging up

  • or down allows for multiple increments or decrements of the current value.

  • Long pressing on the lesser and greater values also allows for a quick change

  • of the current value. Tapping on the current value allows to type in a

  • desired value.

为了在2.3中使用holo风格的DatePickerDialog,只能将ics中holo风格下的DatePickerDialog独立出来,当作一个第三方控件来使用,而不使用android.app.DatePickerDialog。

github上已经有开源项目将这个DatePickerDialog分离了出来。

github地址:https://github.com/SimonVT/android-datepicker

需要注意的是这个DatePickerDialog项目并没有将自身需要用到的numberpicker和calendarview两个控件集成上去,因此你在引用项目的时候需要自己下载作者提供的源码地址,然后手动添加依赖关系。