开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 5 天,点击查看活动详情
以前有写过一篇给PickerView(时间选择器)添加选中背景色的文章,当时是下载了源码,在源码动刀实现了需求。如今,又遇到新的需求,时间限制需要精确到时分秒。什么?我记得PickerView当前是只能限制年月日,库也停止更新。又不想更换库,成本还是蛮大,于是估摸着自己能不能再修改下源码得以实现,说干就干!
首先还是先到Github去看看有没有已经实现的前辈,这种需求应该是有人提的。于是,果不其然一搜就有,这里贴出地址:Android-PickerView
由于该库是针对时分秒限制的产出,并不适合当前项目已经修改过源码库的需求。所以还是得具体看实现代码,然后移植到当前项目中。
根据阅读源码可知,主要修改的逻辑代码在WheelTime和TimePickerView这两个类中。WheelTime主要实现时间的数据和各种属性和限制操作,TimePickerView则提供一些方法给外部调用。
WheelTime
首先来看WheelTime,从源码的属性就可以看出只提供了年月日的限制。这里我们需要新增时分秒属性,然后根据限制逻辑将时分秒的代码加入。
private static final int DEFAULT_START_YEAR = 1900;
private static final int DEFAULT_END_YEAR = 2100;
private static final int DEFAULT_START_MONTH = 1;
private static final int DEFAULT_END_MONTH = 12;
private static final int DEFAULT_START_DAY = 1;
private static final int DEFAULT_END_DAY = 31;
private int startYear = DEFAULT_START_YEAR;
private int endYear = DEFAULT_END_YEAR;
private int startMonth = DEFAULT_START_MONTH;
private int endMonth = DEFAULT_END_MONTH;
private int startDay = DEFAULT_START_DAY;
private int endDay = DEFAULT_END_DAY; //表示31天的
新增以下属性:
private static final int DEFAULT_START_HOUR = 0;
private static final int DEFAULT_START_MINUTE = 0;
private static final int DEFAULT_START_SECOND = 0;
private static final int DEFAULT_END_HOUR = 23;
private static final int DEFAULT_END_MINUTE = 59;
private static final int DEFAULT_END_SECOND = 59;
private int startHour = DEFAULT_START_HOUR;
private int startMinute = DEFAULT_START_MINUTE;
private int startSecond = DEFAULT_START_SECOND;
private int endHour = DEFAULT_END_HOUR;
private int endMinute = DEFAULT_END_MINUTE;
private int endSecond = DEFAULT_END_SECOND;
接下来我们看到源码中设置时分秒没有做任何限制(这里仅贴部分代码),所以在这里需要根据限制的开始、结束时间做对应的逻辑处理。
//时
wv_hours = (WheelView) view.findViewById(R.id.hour);
wv_hours.setAdapter(new NumericWheelAdapter(0, 23));
wv_hours.setCurrentItem(h);
新增逻辑如下,其实也就是根据年月日判断当前时间和限制时间的临界点赋予不同值,分和秒的逻辑也是如此
int tempStartHour;
int tempEndHour;
if (year > startYear || month + 1 > startMonth || day > startDay) {
tempStartHour = DEFAULT_START_HOUR;
} else {
tempStartHour = startHour;
}
if (year < endYear || month + 1 < endMonth || day < endDay) {
tempEndHour = DEFAULT_END_HOUR;
} else {
tempEndHour = endHour;
}
wv_hours.setAdapter(new NumericWheelAdapter(tempStartHour, tempEndHour));
wv_hours.setCurrentItem(h - tempStartHour);
其实到这里大部分工作已经结束了,使用过这个库的同学应该知道,在滑动事件的时候,比如滑动月分,后面的日期会动态根据月份匹配对应数据,这是实时的。那么一定就有个监听器,当设置成功后回调刷新后面的日期。在源码中我们看到setChangedListener函数,我们仅仅需要在这里回调的时候通过下标来判断设置对应的时分秒即可:
wheelView.setOnItemSelectedListener(new OnItemSelectedListener() {
@Override
public void onItemSelected(int index) {
if (wheelView == wv_day) {
setReHour();
} else if (wheelView == wv_hours) {
setReMinute();
} else if (wheelView == wv_minutes) {
setReSecond();
}
if (mSelectChangeCallback != null) {
mSelectChangeCallback.onTimeSelectChanged();
}
}
});
这里的setReHour、setReMinute、setReSecond其实也是那些日期对比和临界值判断赋值后再重新设置到新的适配器中。
最后是最关键的返回当前值,也就是getTime()方法,通过各自的适配器即可拿到,然后根据字符串拼接即可。
TimePickerView
这里不得不多提一嘴,因为新增了时分秒限制,在设置时间区间的时候就势必要增加一些安全判断,具体代码可以到上面提到的地址查看。
总结
到此新增时分秒限制的功能就告一段落了,过程中还是要学会看源码,理解代码意思。这样在新增逻辑的时候就可以参考源码照猫画虎。不要被庞大功能的第三方库给吓倒,功能都是一步一步累积的,每次进步一小步即可。
开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 5 天,点击查看活动详情