时间选择器

写在前面

发现现在做App开发,几乎每次都会用到时间选择器,还有省市区三级联动什么的,今天将自己一直常用的,也是自己比较喜欢的一个自定义时间选择器贴出来,下次用的之后直接copy。俗话说的好,不会偷懒的程序员不是好程序员么。其实个人觉得这些既定的一些控件或者是代码,没必要每次都去重写,做一个可以通用的,下次直接使用其实也是一个很不错的选择,能提高你的工作效率,还能锻炼你优化代码的能力。当然,这些你要copy的代码必须了解他。废话好像有点多。好,进入正题。。。

效果图

自定义控件

PickerView之前是从GayHub上down上下来的,具体是哪位大神我也忘了,在此先向原作者致敬。自己用的修改了一些,加了一个Listene,做了一个回调。由于代码比较多,就贴出两个主要的方法。

1、绘制中间text的方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
private void drawData(Canvas canvas) {
if (mDataList == null || mDataList.size() == 0) {
return;
}
// 先绘制选中的text再往上往下绘制其余的text
float scale = parabola(mViewHeight / 4.0f, mMoveLen);
float size = (mMaxTextSize - mMinTextSize) * scale + mMinTextSize;
mPaint.setTextSize(size);
mPaint.setAlpha((int) ((mMaxTextAlpha - mMinTextAlpha) * scale + mMinTextAlpha));
// text居中绘制,注意baseline的计算才能达到居中,y值是text中心坐标
float x = (float) (mViewWidth / 2.0);
float y = (float) (mViewHeight / 2.0 + mMoveLen);
FontMetricsInt fmi = mPaint.getFontMetricsInt();
float baseline = (float) (y - (fmi.bottom / 2.0 + fmi.top / 2.0));

canvas.drawText(mDataList.get(mCurrentSelected).first, x, baseline, mPaint);
// 绘制上方data
for (int i = 1; (mCurrentSelected - i) >= 0; i++) {
drawOtherText(canvas, i, -1);
}
// 绘制下方data
for (int i = 1; (mCurrentSelected + i) < mDataList.size(); i++) {
drawOtherText(canvas, i, 1);
}

}
2、绘制上下text的方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/**
* @param canvas
* @param position 距离mCurrentSelected的差值
* @param type 1表示向下绘制,-1表示向上绘制
*/
private void drawOtherText(Canvas canvas, int position, int type)
{
float d = (float) (MARGIN_ALPHA * mMinTextSize * position + type
* mMoveLen);
float scale = parabola(mViewHeight / 4.0f, d);
float size = (mMaxTextSize - mMinTextSize) * scale + mMinTextSize;
mPaint.setTextSize(size);
mPaint.setAlpha((int) ((mMaxTextAlpha - mMinTextAlpha) * scale + mMinTextAlpha));
float y = (float) (mViewHeight / 2.0 + type * d);
FontMetricsInt fmi = mPaint.getFontMetricsInt();
float baseline = (float) (y - (fmi.bottom / 2.0 + fmi.top / 2.0));
canvas.drawText(mDataList.get(mCurrentSelected + type * position).first,
(float) (mViewWidth / 2.0), baseline, mPaint);
}

数据填充

通过滚动监听来动态的设置时间日期数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
int thisYear = new Date().getYear() + 1900;
List<Pair<String, Object>> yearList = new ArrayList<>();
for (int i = 1900; i <= thisYear; i++) {
yearList.add(new Pair<String, Object>(String.valueOf(i), i));
}
mYearPickerView.setData(yearList);
mYearPickerView.setOnSelectListener(this);
if (year >= 1900 && year <= new Date().getYear() + 1900) {
mYearPickerView.setSelected(year - 1900);
}

List<Pair<String, Object>> monthList = new ArrayList<>();
for (int i = 1; i <= 12 ; i++) {
monthList.add(new Pair<String, Object>(String.valueOf(i), i));
}
mMonthPickerView.setData(monthList);
mMonthPickerView.setOnSelectListener(this);
if (month >= 1 && month <= 12) {
mMonthPickerView.setSelected(month - 1);
}

这个比较简单,所以就大概总结一下。然后deno源码放在了GayHub上:PickDialog