自定义DateView控件
2014-11-21
最近因为项目需要自定义一个日期控件,我花了一个多小时写了这个控件。虽然跟设计效果图还有点细微差别,但是这个可以慢慢修改。
public class DateView extends View {
private static final int DAY_TEXT_SIZE = 32;
private static final int MONTH_TEXT_SIZE = 16;
private int mDay;
private int mMonth;
private int mYear;
private TextPaint mDayPaint;
private TextPaint mMonthPaint;
public DateView(Context context) {
super(context);
initView();
}
public DateView(Context context, AttributeSet attrs) {
super(context, attrs);
initView();
}
public DateView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initView();
}
private void initView() {
mDayPaint = new TextPaint(TextPaint.ANTI_ALIAS_FLAG);
mDayPaint.setColor(0xff333333);
mMonthPaint = new TextPaint(mDayPaint);
mDayPaint.setTextSize(dip2px(getContext(), DAY_TEXT_SIZE));
// setBackgroundColor(Color.TRANSPARENT);
setDate(Calendar.getInstance().getTimeInMillis()/1000);
setMinimumWidth(dip2px(getContext(),80));
setMinimumHeight(dip2px(getContext(), 80));
}
/**
* 显示年月日
* @param timeInSeconds 以秒为单位
*/
public void setDate(long timeInSeconds) {
Calendar ca = Calendar.getInstance();
ca.clear();
ca.setTimeInMillis(timeInSeconds *1000);
mMonth = ca.get(Calendar.MONTH) + 1;
mYear = ca.get(Calendar.YEAR);
mDay = ca.get(Calendar.DAY_OF_MONTH);
mMonthPaint.setTextSize(dip2px(getContext(), MONTH_TEXT_SIZE));
invalidate();
}
/**
* 设置时间,当year为0时,表示不需要显示年,只显示月日
* @param day 1-31
* @param month 1-12
* @param year >= 0,0表示不显示年
*/
public void setDate(int day, int month, int year) {
mDay = day;
mMonth = month;
if (mMonth == 0) mMonth = 1;
mYear = year;
if (mYear == 0) {
mMonthPaint.setTextSize(dip2px(getContext(), MONTH_TEXT_SIZE+2));
} else {
mMonthPaint.setTextSize(dip2px(getContext(), MONTH_TEXT_SIZE));
}
invalidate();
}
public static int dip2px(Context context, float dpValue) {
final float scale = context.getResources().getDisplayMetrics().density;
return (int) (dpValue * scale + 0.5f);
}
public void setTextColor(int color) {
mDayPaint.setColor(color);
mMonthPaint.setColor(color);
invalidate();
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
String dayText = String.valueOf(String.format("%02d", mDay));
int dayTextLen = (int) mDayPaint.measureText(dayText);
int canvasWith = canvas.getWidth();
int canvasHeight = canvas.getHeight();
canvas.drawLine(canvasWith*0.75f, canvasHeight*0.25f, canvasWith*0.25f, canvasHeight*0.75f, mDayPaint);
canvas.drawText(dayText, canvasWith/2-dayTextLen, canvasHeight/2+mDayPaint.getFontMetrics().descent/2, mDayPaint);
Paint.FontMetrics fontMetrics = mMonthPaint.getFontMetrics();
String monthText = String.valueOf(mMonth) + "月";
// int monthTextLen = (int)mMonthPaint.measureText(monthText);
float textHeight = Math.abs(fontMetrics.ascent) + Math.abs(fontMetrics.descent) + fontMetrics.leading;
if (mYear > 0) {
String yearText = String.valueOf(mYear);
canvas.drawText(yearText, canvasWith/2 - mMonthPaint.getTextSize()*0.5f, canvasHeight/2 + mMonthPaint.getTextSize()*1.5f, mMonthPaint);
canvas.drawText(monthText, canvasWith/2 + mMonthPaint.getTextSize()/2, canvasHeight/2+mMonthPaint.getTextSize()*0.5f, mMonthPaint);
} else {
canvas.drawText(monthText, canvasWith/2, canvasHeight/2+mMonthPaint.getTextSize(), mMonthPaint);
}
}
}
这最不好做的就是算字的位置,文字的渲染是基于baseline的,我的理解是Rect的左下角。关于canvas的draw还有很多不懂,好好学习
Category: Android Tagged: Android 自定义控件 日期控件