Calender 是 Android 平台的一个日历显示组件,可以显示一整月历。项目适合初学者学习组件开发,项目如图:

开源项目之Android Calender(日历组件)_第1张图片

开源项目之Android Calender(日历组件)_第2张图片


该组件是在ImageView基础上扩展出来的,而Cell 是组件的格子,负责显示日期等。

public class Cell {private static final String TAG = "Cell";protected Rect mBound = null;protected int mDayOfMonth = 1; // from 1 to 31protected Paint mPaint = new Paint(Paint.SUBPIXEL_TEXT_FLAG| Paint.ANTI_ALIAS_FLAG);int dx, dy;public Cell(int dayOfMon, Rect rect, float textSize, boolean bold) {mDayOfMonth = dayOfMon;mBound = rect;mPaint.setTextSize(textSize/* 26f */);mPaint.setColor(Color.BLACK);if (bold)mPaint.setFakeBoldText(true);dx = (int) mPaint.measureText(String.valueOf(mDayOfMonth)) / 2;dy = (int) (-mPaint.ascent() + mPaint.descent()) / 2;}public Cell(int dayOfMon, Rect rect, float textSize) {this(dayOfMon, rect, textSize, false);}protected void draw(Canvas canvas) { //自绘canvas.drawText(String.valueOf(mDayOfMonth), mBound.centerX() - dx,mBound.centerY() + dy, mPaint);}public int getDayOfMonth() { //日期return mDayOfMonth;}public boolean hitTest(int x, int y) { //是否单击return mBound.contains(x, y);}public Rect getBound() { //获取范围return mBound;}public String toString() {return String.valueOf(mDayOfMonth) + "(" + mBound.toString() + ")";}}
关键是CalendarView,它负责布局 显示、操作等工作,源码如下:

public class CalendarView extends ImageView {private static int WEEK_TOP_MARGIN = 74;private static int WEEK_LEFT_MARGIN = 40;private static int CELL_WIDTH = 58;private static int CELL_HEIGH = 53;private static int CELL_MARGIN_TOP = 92;private static int CELL_MARGIN_LEFT = 39;private static float CELL_TEXT_SIZE;private static final String TAG = "CalendarView";private Calendar mRightNow = null;private Drawable mWeekTitle = null;private Cell mToday = null;private Cell[][] mCells = new Cell[6][7];private OnCellTouchListener mOnCellTouchListener = null;MonthDisplayHelper mHelper;Drawable mDecoration = null;public interface OnCellTouchListener {public void onTouch(Cell cell);}public CalendarView(Context context) {this(context, null);}public CalendarView(Context context, AttributeSet attrs) {this(context, attrs, 0);}public CalendarView(Context context, AttributeSet attrs, int defStyle) {super(context, attrs, defStyle);mDecoration = context.getResources().getDrawable(R.drawable.typeb_calendar_today);initCalendarView();}private void initCalendarView() {mRightNow = Calendar.getInstance();// prepare static varsResources res = getResources();WEEK_TOP_MARGIN = (int) res.getDimension(R.dimen.week_top_margin);WEEK_LEFT_MARGIN = (int) res.getDimension(R.dimen.week_left_margin);CELL_WIDTH = (int) res.getDimension(R.dimen.cell_width);CELL_HEIGH = (int) res.getDimension(R.dimen.cell_heigh);CELL_MARGIN_TOP = (int) res.getDimension(R.dimen.cell_margin_top);CELL_MARGIN_LEFT = (int) res.getDimension(R.dimen.cell_margin_left);CELL_TEXT_SIZE = res.getDimension(R.dimen.cell_text_size);// set backgroundsetImageResource(R.drawable.background);mWeekTitle = res.getDrawable(R.drawable.calendar_week);mHelper = new MonthDisplayHelper(mRightNow.get(Calendar.YEAR),mRightNow.get(Calendar.MONTH));}private void initCells() {class _calendar {public int day;public boolean thisMonth;public _calendar(int d, boolean b) {day = d;thisMonth = b;}public _calendar(int d) {this(d, false);}};_calendar tmp[][] = new _calendar[6][7];for (int i = 0; i < tmp.length; i++) {int n[] = mHelper.getDigitsForRow(i);for (int d = 0; d < n.length; d++) {if (mHelper.isWithinCurrentMonth(i, d))tmp[i][d] = new _calendar(n[d], true);elsetmp[i][d] = new _calendar(n[d]);}}Calendar today = Calendar.getInstance();int thisDay = 0;mToday = null;if (mHelper.getYear() == today.get(Calendar.YEAR)&& mHelper.getMonth() == today.get(Calendar.MONTH)) {thisDay = today.get(Calendar.DAY_OF_MONTH);}// build cellsRect Bound = new Rect(CELL_MARGIN_LEFT, CELL_MARGIN_TOP, CELL_WIDTH+ CELL_MARGIN_LEFT, CELL_HEIGH + CELL_MARGIN_TOP);for (int week = 0; week < mCells.length; week++) {for (int day = 0; day < mCells[week].length; day++) {if (tmp[week][day].thisMonth) {if (day == 0 || day == 6)mCells[week][day] = new RedCell(tmp[week][day].day,new Rect(Bound), CELL_TEXT_SIZE);elsemCells[week][day] = new Cell(tmp[week][day].day,new Rect(Bound), CELL_TEXT_SIZE);} else {mCells[week][day] = new GrayCell(tmp[week][day].day,new Rect(Bound), CELL_TEXT_SIZE);}Bound.offset(CELL_WIDTH, 0); // move to next column// get todayif (tmp[week][day].day == thisDay && tmp[week][day].thisMonth) {mToday = mCells[week][day];mDecoration.setBounds(mToday.getBound());}}Bound.offset(0, CELL_HEIGH); // move to next row and first columnBound.left = CELL_MARGIN_LEFT;Bound.right = CELL_MARGIN_LEFT + CELL_WIDTH;}}@Overridepublic void onLayout(boolean changed, int left, int top, int right,int bottom) {Rect re = getDrawable().getBounds();WEEK_LEFT_MARGIN = CELL_MARGIN_LEFT = (right - left - re.width()) / 2;mWeekTitle.setBounds(WEEK_LEFT_MARGIN, WEEK_TOP_MARGIN,WEEK_LEFT_MARGIN + mWeekTitle.getMinimumWidth(),WEEK_TOP_MARGIN + mWeekTitle.getMinimumHeight());initCells();super.onLayout(changed, left, top, right, bottom);}public void setTimeInMillis(long milliseconds) {mRightNow.setTimeInMillis(milliseconds);initCells();this.invalidate();}public int getYear() {return mHelper.getYear();}public int getMonth() {return mHelper.getMonth();}public void nextMonth() {mHelper.nextMonth();initCells();invalidate();}public void previousMonth() {mHelper.previousMonth();initCells();invalidate();}public boolean firstDay(int day) {return day == 1;}public boolean lastDay(int day) {return mHelper.getNumberOfDaysInMonth() == day;}public void goToday() {Calendar cal = Calendar.getInstance();mHelper = new MonthDisplayHelper(cal.get(Calendar.YEAR),cal.get(Calendar.MONTH));initCells();invalidate();}public Calendar getDate() {return mRightNow;}@Overridepublic boolean onTouchEvent(MotionEvent event) {if (mOnCellTouchListener != null) {for (Cell[] week : mCells) {for (Cell day : week) {if (day.hitTest((int) event.getX(), (int) event.getY())) {mOnCellTouchListener.onTouch(day);}}}}return super.onTouchEvent(event);}public void setOnCellTouchListener(OnCellTouchListener p) {mOnCellTouchListener = p;}@Overrideprotected void onDraw(Canvas canvas) {// draw backgroundsuper.onDraw(canvas);mWeekTitle.draw(canvas);// draw cellsfor (Cell[] week : mCells) {for (Cell day : week) {day.draw(canvas);}}// draw todayif (mDecoration != null && mToday != null) {mDecoration.draw(canvas);}}public class GrayCell extends Cell {public GrayCell(int dayOfMon, Rect rect, float s) {super(dayOfMon, rect, s);mPaint.setColor(Color.LTGRAY);}}private class RedCell extends Cell {public RedCell(int dayOfMon, Rect rect, float s) {super(dayOfMon, rect, s);mPaint.setColor(0xdddd0000);}}}

是不是非常简单?

项目下载

更多相关文章

  1. 深入解析:Android卡顿检测及优化项目实战经验总结
  2. 史上最强NDK入门项目实战
  3. Android 组件化的应用 模块通信问题解决
  4. Github开源Android资源整理(十一)优秀项目
  5. Android界面组件基本用法
  6. android Parcelable项目中的应用
  7. Android引入项目作为依赖(module)
  8. Android - 实训项目总结
  9. Android 项目快速更改包名的方法

随机推荐

  1. [转]Ubuntu搭建Android环境
  2. android 监听手机屏幕唤醒和睡眠广播
  3. android的Environment类 .
  4. Android.Accessibility包之AccessiblityS
  5. Android 手动设置屏幕方向后不能自动转屏
  6. 获取谷歌日历日程数据
  7. Android 首选网络模式默认值的修改方法
  8. Android: 触屏fling/scroll/drag的区别及
  9. android studio每次启动都要在fetching A
  10. Android——四大组件、六大布局、五大存