自定义Android日期选择器

自定义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);
}

共有五种主题,可以选择:

  1. public static final int THEME_TRADITIONAL = 1;
  2. public static final int THEME_HOLO_DARK = 2;
  3. public static final int THEME_HOLO_LIGHT = 3;
  4. public static final int THEME_DEVICE_DEFAULT_DARK = 4;
  5. 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来分别调用。

<DatePicker
    android: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网址:https://github.com/AigeStudio/WheelPicker

另一种方案

上一个方案还没去执行的时候,我又发现了一个兄弟写的控件,DatePickerView。
博客网址:https://blog.csdn.net/oLimxing/article/details/112475099
DatePickerView网址:https://github.com/limxing/DatePickerView
这个大佬是通过控制RecyclerView来达到了NumberPicker同样的效果。
在这里插入图片描述

最终我选择的是这种方案。
不过这个控件没有实现年月日的循环,布局和需求也有出入,但是可以下载到源码嘛,一番修修改改,还是达到了开头想要的效果,想要大佬的脑袋瓜。
改我会,代码我也看得懂,可是让我自己写,好难哇。
括弧,WheelPicker的代码也很有必要去看看,假如我是个认真的人。
最终效果:https://gitee.com/djyan/DatePickerView

猜你喜欢

转载自blog.csdn.net/changhuzichangchang/article/details/127074226
今日推荐