附上详细的CalendarView代码:
1
16 package org.warnier.zhang.support.v1.widget;
17
18 import android.content.Context;
19 import android.graphics.Canvas;
20 import android.graphics.Color;
21 import android.graphics.Paint;
22 import android.util.AttributeSet;
23 import android.view.View;
24
25 import java.util.Calendar;
26 import java.util.GregorianCalendar;
27
28 /**
29 * This class is a calendar widget for displaying lastest seven dates in
30 * a single line. The start of date supported by this CalendarView is
31 * configurable.
32 */
33 public class CalendarView extends View {
34 private static final int zh_CN = 86;
35 private static final int en_US = 1;
36
37 private Context mContext;
38 private Paint mTextPaint;
39 private Paint mRectPaint;
40 private Paint mCirclePaint;
41 private int mWidthMeasureSpec;
42 private float mCellMeasureSpec;
43 private String[][] mDataSet = new String[2][7];
44 private Calendar mCalendar;
45 private int mDayOfMonth;
46 private int mDayOfWeek;
47
48 public CalendarView(Context context) {
49 super(context);
50 mContext = context;
51 init();
52 }
53
54 public CalendarView(Context context, AttributeSet attrs) {
55 super(context, attrs);
56 mContext = context;
57 init();
58 }
59
60 private void init() {
61 mTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
62 mTextPaint.setTextAlign(Paint.Align.LEFT);
63 mTextPaint.setTextSize(24);
64 mRectPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
65 mRectPaint.setStyle(Paint.Style.FILL);
66 mRectPaint.setColor(Color.parseColor("#4285F4"));
67 mCirclePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
68 mCirclePaint.setStyle(Paint.Style.FILL);
69 mCirclePaint.setColor(Color.parseColor("#4285F4"));
70 initDate();
71 }
72
73 private void initDate() {
74 mCalendar = new GregorianCalendar();
75 mDayOfMonth = mCalendar.get(Calendar.DAY_OF_MONTH);
76 mDayOfWeek = mCalendar.get(Calendar.DAY_OF_WEEK);
77 mDataSet[0] = getWeekdayNames(en_US);
78 mDataSet[1] = fillDataSet(mDayOfMonth, mDayOfWeek);
79 if (mDataSet[1] == null) {
80 throw new IllegalStateException("日期数据异常!");
81 }
82 }
83
84 private String[] getWeekdayNames(int locale) {
85 if (locale == en_US) {
86 return new String[]{"S", "M", "T", "W", "S", "F", "S"};
87 } else if (locale == zh_CN) {
88 return new String[]{"日", "一", "二", "三", "四", "五", "六"};
89 } else {
90 throw new IllegalStateException("日期格式异常!");
91 }
92 }
93
94 @Override
95 protected void onSizeChanged(int w, int h, int oldw, int oldh) {
96 super.onSizeChanged(w, h, oldw, oldh);
97 mWidthMeasureSpec = w;
98 mCellMeasureSpec = mWidthMeasureSpec / 7.0f;
99 mTextPaint.setTextSize(mCellMeasureSpec / 3.0f);
100 }
101
102 @Override
103 protected void onDraw(Canvas canvas) {
104 super.onDraw(canvas);
105 canvas.drawRect(mWidthMeasureSpec, mCellMeasureSpec, 0, 0, mRectPaint);
106 for (int i = 0; i < 2; i++) {
107 setPaintColor(i);
108 for (int j = 0; j < 7; j++) {
109 float x = (float) ((j + 0.5) * mCellMeasureSpec - mTextPaint.measureText(mDataSet[i][j]) / 2);
110 float y = (float) ((i + 0.8) * mCellMeasureSpec - mTextPaint.measureText(mDataSet[i][j], 0, 1) / 2);
111 /**
112 * 用“圆形”标注当前日期;
113 */
114 if (mDataSet[i][j].equals(String.valueOf(mDayOfMonth))) {
115 float cx = x + mTextPaint.measureText(mDataSet[i][j]) * 0.5f;
116 float cy = y - mTextPaint.measureText(mDataSet[i][j]) * 0.42f;
117 canvas.drawCircle(cx, cy, mCellMeasureSpec / 3.0f, mCirclePaint);
118 setPaintColor(0);
119 canvas.drawText(mDataSet[i][j], x, y, mTextPaint);
120 setPaintColor(1);
121 } else {
122 canvas.drawText(mDataSet[i][j], x, y, mTextPaint);
123 }
124 }
125 }
126 }
127
128 private void setPaintColor(int rowSpec) {
129 if (rowSpec == 0) {
130 mTextPaint.setColor(Color.parseColor("#FFFFFF"));
131 } else {
132 mTextPaint.setColor(Color.parseColor("#565656"));
133 }
134 }
135
136 private String[] fillDataSet(int dayOfMonth, int dayOfWeek) {
137 int index = 0;
138 String[] date = {
139 "1", "2", "3", "4", "5", "6", "7"
140 };
141
142 for (int i = 0; i < date.length; i++) {
143 if (date[i].equals("" + dayOfWeek)) {
144 date[i] = "" + dayOfMonth;
145 index = i;
146 }
147 }
148 for (int i = index - 1; i >= 0; i--) {
149 mCalendar.add(Calendar.DAY_OF_MONTH, -1);
150 date[i] = mCalendar.get(Calendar.DAY_OF_MONTH) + "";
151 }
152 mCalendar.set(Calendar.DAY_OF_MONTH, dayOfMonth);
153 for (int i = index + 1; i < date.length; i++) {
154 mCalendar.add(Calendar.DAY_OF_MONTH, 1);
155 date[i] = mCalendar.get(Calendar.DAY_OF_MONTH) + "";
156 }
157
158 return date;
159 }
160 }
当然,CalendarView中存在下述方面的不足:
(1)没有添加对layout XML文件的支持;
(2)日历每个选项的绘制没有完全水平,垂直居中;
(3)两位数和单位数的日期显示间隔,高度不一致;
(4)标注当前日期的圆形没能够以字的中心作为圆心;
欢迎各位读者交流心得,共同完善CalendarView。
完整的Android Studio工程下载链接:链接: http://pan.baidu.com/s/1eQAT9ei 密码: 4pqh。
Github链接稍后推送,等待更新...