自定义Android日期选择器
背景调研思考和总结另一种方案背景
设计小姐姐,给了一个如下所示的需求,很显然这是一个日期选择器
调研
目前ANDROID主流的日期选择器,是官方提供的DatePickerDialog,创建DatePickerDialog如下,它接收一个themeResId,用来设置对话框的主题。
public DatePickerDialog(@NonNull Context context, @StyleRes int themeResId,@Nullable OnDateSetListener listener, int year, int monthOfYear, int dayOfMonth) {this(context, themeResId, listener, null, year, monthOfYear, dayOfMonth);}
共有五种主题,可以选择:
public static final int THEME_TRADITIONAL = 1;public static final int THEME_HOLO_DARK = 2;public static final int THEME_HOLO_LIGHT = 3;public static final int THEME_DEVICE_DEFAULT_DARK = 4;public static final int THEME_DEVICE_DEFAULT_LIGHT = 5;
第1个传统主题THEME_TRADITIONAL :
第2个列表选择框THEME_HOLO_DARK ;
第3个列表选择框THEME_HOLO_LIGHT ;
第4个列表选择框THEME_DEVICE_DEFAULT_DARK ;
第5个列表选择框THEME_DEVICE_DEFAULT_LIGHT ;
思考和总结
综上来看,第3个还比较符合我们的UI,但是它右边还多了一部分(上面举例,是5.1系统上的示意图,6.0以后第3个其实只有左半部分),而且色彩啊边距啊都不符合我们的需求,如果这些可以自定义就好了。
于是我去看了源码:
如下,DatePickerDialog说白了就是AlertDialog上放了一个DatePicker和两个button。所以这里重要的是DatePicker。
查看DatePicker的源码,调用DatePicker的时候,会传入一个datePickerMode,这里根据mMode来分别调用。
<DatePickerandroid:layout_width="wrap_content"android:layout_height="wrap_content" android:datePickerMode="spinner"/>
我们要看的是spinner(滚动列表)的模式,跟一下代码,可以看到它加载了一个date_picker_legacy的布局
createSpinnerUIDelegate-》DatePickerSpinnerDelegate
找到这个布局date_picker_legacy,可以看到DatePicker的实际实现,其实是三个NumberPicker
然而系统提供的NumerPicker对外可以调用的接口(6.0版本上)非常少,只有预设范围等,根本不支持我们自定义布局。轻量级自定义的话(继承NumberPicker),也可以完成部分需求,比如修改主题色,只显示年月,修改字体颜色大小等等,但是一些比如选中时的背景之类的需求是完成不了的。
综上,我们只能通过重量级自定义来完成,也就是完全写一个新的类似于NumberPicker的控件,然后去绘制选中时的背景、文字字体颜色大小。思考到这,我想放弃了,因为我觉得好难哇。但是我发现有一个现成的控件WheelPicker可以使用。WheelPicker实现基于原生Android NumberPicker,除了实现NumberPicker的标准方法外,还提供了更多自定义的属性,项目中如要替换,仅需要将NumberPicker替换成WheelPicker即可。我估摸着换成这个是可以实现UI小姐姐给我的需求的。
WheelPicker网址:/AigeStudio/WheelPicker
另一种方案
上一个方案还没去执行的时候,我又发现了一个兄弟写的控件,DatePickerView。
博客网址:/oLimxing/article/details/112475099
DatePickerView网址:/limxing/DatePickerView
这个大佬是通过控制RecyclerView来达到了NumberPicker同样的效果。
最终我选择的是这种方案。
不过这个控件没有实现年月日的循环,布局和需求也有出入,但是可以下载到源码嘛,一番修修改改,还是达到了开头想要的效果,想要大佬的脑袋瓜。
改我会,代码我也看得懂,可是让我自己写,好难哇。
括弧,WheelPicker的代码也很有必要去看看,假如我是个认真的人。
最终效果:/djyan/DatePickerView