1、自定义view日历星期
public class WeekDayView extends View{
//上横线颜色
private int mTopLineColor = Color.parseColor("#CCE4F2");
//下横线颜色
private int mBottomLineColor = Color.parseColor("#CCE4F2");
//周一到周五的颜色
private int mWeekdayColor = Color.parseColor("#1FC2F3");
//周六、周日的颜色
private int mWeekendColor = Color.parseColor("#fa4451");
//线的宽度
private int mStrokeWidth = 4;
private int mWeekSize = 14;
private Paint paint;
private DisplayMetrics mDisplayMetrics;
private String[] weekString = new String[]{"S","M","T","W","T","F","S"};
public WeekDayView(Context context, AttributeSet attrs) {
super(context, attrs);
mDisplayMetrics = getResources().getDisplayMetrics();
paint = new Paint();
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
if(heightMode == MeasureSpec.AT_MOST){
heightSize = mDisplayMetrics.densityDpi * 30;
}
if(widthMode == MeasureSpec.AT_MOST){
widthSize = mDisplayMetrics.densityDpi * 300;
}
//测量高度和宽度
setMeasuredDimension(widthSize, heightSize);
}
@Override
protected void onDraw(Canvas canvas) {
int width = getWidth();
int height = getHeight();
//进行画上下线
paint.setAntiAlias(true); //设置抗锯齿的效果
paint.setStyle(Paint.Style.STROKE); //设置画笔的样式为描边
//设置画笔的颜色
paint.setColor(mTopLineColor);
//设置画笔的宽度
paint.setStrokeWidth(mStrokeWidth);
//用指定的开始和停止x、y坐标绘制线段,使用指定的油漆
canvas.drawLine(0, 0, width, 0, paint);
//设置下横线的画笔颜色
paint.setColor(mBottomLineColor);
canvas.drawLine(0, height, width, height, paint);
//设置画笔的样式
paint.setStyle(Paint.Style.FILL);
paint.setTextSize(mWeekSize * mDisplayMetrics.scaledDensity);
int columnWidth = width / 7;
for(int i=0;i < weekString.length;i++){
String text = weekString[i];
int fontWidth = (int) paint.measureText(text);
int startX = columnWidth * i + (columnWidth - fontWidth)/2;
int startY = (int) (height/2 - (paint.ascent() + paint.descent())/2);
if(text.indexOf("R") > -1|| text.indexOf("S") > -1){
paint.setColor(mWeekendColor);
}else{
paint.setColor(mWeekdayColor);
}
canvas.drawText(text, startX, startY, paint);
}
}
/**
* 设置顶线的颜色
* @param mTopLineColor
*/
public void setmTopLineColor(int mTopLineColor) {
this.mTopLineColor = mTopLineColor;
}
/**
* 设置底线的颜色
* @param mBottomLineColor
*/
public void setmBottomLineColor(int mBottomLineColor) {
this.mBottomLineColor = mBottomLineColor;
}
/**
* 设置周一-五的颜色
* @return
*/
public void setmWeekdayColor(int mWeekdayColor) {
this.mWeekdayColor = mWeekdayColor;
}
/**
* 设置周六、周日的颜色
* @param mWeekendColor
*/
public void setmWeekendColor(int mWeekendColor) {
this.mWeekendColor = mWeekendColor;
}
/**
* 设置边线的宽度
* @param mStrokeWidth
*/
public void setmStrokeWidth(int mStrokeWidth) {
this.mStrokeWidth = mStrokeWidth;
}
/**
* 设置字体的大小
* @param mWeekSize
*/
public void setmWeekSize(int mWeekSize) {
this.mWeekSize = mWeekSize;
}
/**
* 设置星期的形式
* @param weekString
* 默认值 "日","一","二","三","四","五","六"
*/
public void setWeekString(String[] weekString) {
this.weekString = weekString;
}
}
2、简单自定义日历界面
public class MyMediaDayController extends View {
private static final int NUM_COLUMNS = 7;
private static final int NUM_ROWS = 6;
private int mColumnSize,mRowSize;//行宽、高
private int [][] daysString;//天数
private DisplayMetrics mDisplayMetrics;
private Paint mPaint;//画笔
private int mCurrYear, mCurrMonth, mCurrDay;//年月日
private int mSelYear, mSelMonth, mSelDay;//设置年月日
private int mDaySize = 14;//天数字体大小
private int mMonthDays;//一个月中有几天
private int mDayColor = Color.parseColor("#666666");//设置字体颜色
public MyMediaDayController(Context context, AttributeSet attrs) {
super(context, attrs);
mDisplayMetrics = getResources().getDisplayMetrics();
Calendar calendar = Calendar.getInstance();
mPaint = new Paint();
mPaint.setAntiAlias(true);
mCurrYear = calendar.get(Calendar.YEAR);
mCurrMonth = calendar.get(Calendar.MONTH) + 1;
mCurrDay = calendar.get(Calendar.DATE);
setSelectYearMonth(mCurrYear, mCurrMonth, 0);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
if (heightMode == MeasureSpec.AT_MOST) {
heightSize = mDisplayMetrics.densityDpi * 200;
}
if (widthMode == MeasureSpec.AT_MOST) {
widthSize = mDisplayMetrics.densityDpi * 300;
}
setMeasuredDimension(widthSize, heightSize);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
initSize();
daysString = new int[6][7];
mPaint.setTextSize(mDaySize * mDisplayMetrics.scaledDensity);
String dayString;
Calendar calendar = Calendar.getInstance();
mSelYear = calendar.get(Calendar.YEAR);
mSelMonth = calendar.get(Calendar.MONTH) + 1;
calendar.set(Calendar.YEAR, mSelYear);//先指定年份
calendar.set(Calendar.MONTH, mSelMonth - 1);//再指定月份 Java月份从0开始算
mMonthDays = calendar.getActualMaximum(Calendar.DATE);//获取指定年份中指定月份有几天
calendar.set(Calendar.DAY_OF_MONTH, 1); //获取指定年份月份中指定某天是星期几
int weekNumber = calendar.get(Calendar.DAY_OF_WEEK);//周几
for(int day = 0; day < mMonthDays; day++){
dayString = (day + 1) + "";
int column = (day + weekNumber - 1) % 7;//一行中的第几个
int row = (day + weekNumber - 1) / 7;//第几列
daysString[row][column] = day + 1;
int startX = (int) (mColumnSize * column + (mColumnSize - mPaint.measureText(dayString))/2);
int startY = (int) (mRowSize * row + mRowSize/2 - (mPaint.ascent() + mPaint.descent())/2);
mPaint.setColor(mDayColor);
canvas.drawText(dayString, startX, startY, mPaint);
}
}
@Override
public boolean onTouchEvent(MotionEvent event) {
return super.onTouchEvent(event);
}
/**
* 初始化列宽行高
*/
private void initSize(){
mColumnSize = getWidth() / NUM_COLUMNS;
mRowSize = getHeight() / NUM_ROWS;
}
/**
* 设置年月
* @param year
* @param month
*/
private void setSelectYearMonth(int year,int month,int day){
mSelYear = year;
mSelMonth = month;
mSelDay = day;
}
}
3.xml代码
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<com.eiboran.ace.widget.WeekDayView
android:layout_width="match_parent"
android:layout_height="40dp" />
<com.eiboran.ace.widget.MyMediaDayController
android:layout_width="match_parent"
android:layout_height="160dp" />
</LinearLayout>
4.自定义日历界面带标记界面
public class MyMediaDayController extends View {
private static final int NUM_COLUMNS = 7;
private static final int NUM_ROWS = 6;
private int mColumnSize,mRowSize;//行宽、高
private int [][] daysString;//天数
private DisplayMetrics mDisplayMetrics;
private Paint mPaint;//画笔
private int mCurrYear, mCurrMonth, mCurrDay;//年月日
private int mSelYear, mSelMonth, mSelDay;//设置年月日
private int mDaySize = 14;//天数字体大小
private int mMonthDays;//一个月中有几天
private int mDayColor = Color.parseColor("#FFFFFF");//设置字体颜色
private int m15DayColor = Color.parseColor("#00BFFF");
private int m30DayColor = Color.parseColor("#FF7F50");
private int m0DayColor = Color.parseColor("#FF0000");
public MyMediaDayController(Context context, AttributeSet attrs) {
super(context, attrs);
mDisplayMetrics = getResources().getDisplayMetrics();
Calendar calendar = Calendar.getInstance();
mPaint = new Paint();
mPaint.setAntiAlias(true);
mCurrYear = calendar.get(Calendar.YEAR);
mCurrMonth = calendar.get(Calendar.MONTH) + 1;
mCurrDay = calendar.get(Calendar.DATE);
setSelectYearMonth(mCurrYear, mCurrMonth, 0);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
if (heightMode == MeasureSpec.AT_MOST) {
heightSize = mDisplayMetrics.densityDpi * 200;
}
if (widthMode == MeasureSpec.AT_MOST) {
widthSize = mDisplayMetrics.densityDpi * 300;
}
setMeasuredDimension(widthSize, heightSize);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
initSize();
daysString = new int[6][7];
mPaint.setTextSize(mDaySize * mDisplayMetrics.scaledDensity);
String dayString;
Calendar calendar = Calendar.getInstance();
mSelYear = calendar.get(Calendar.YEAR);
mSelMonth = calendar.get(Calendar.MONTH) + 1;
calendar.set(Calendar.YEAR, mSelYear);//先指定年份
calendar.set(Calendar.MONTH, mSelMonth - 1);//再指定月份 Java月份从0开始算
mMonthDays = calendar.getActualMaximum(Calendar.DATE);//获取指定年份中指定月份有几天
calendar.set(Calendar.DAY_OF_MONTH, 1); //获取指定年份月份中指定某天是星期几
int weekNumber = calendar.get(Calendar.DAY_OF_WEEK);//周几
for(int day = 0; day < mMonthDays; day++){
dayString = (day + 1) + "";
int column = (day + weekNumber - 1) % 7;//一行中的第几个
int row = (day + weekNumber - 1) / 7;//第几列
daysString[row][column] = day + 1;
int startX = (int) (mColumnSize * column + (mColumnSize - mPaint.measureText(dayString))/2);
int startY = (int) (mRowSize * row + mRowSize/2 - (mPaint.ascent() + mPaint.descent())/2);
//给日期绘制背景
int startRecX = mColumnSize * column;
int startRecY = mRowSize * row;
int endRecX = startRecX + mColumnSize;
int endRecY = startRecY + mRowSize;
if (day > 15 ){
mPaint.setColor(m15DayColor);
RectF mColorWheelRectangleS = new RectF(startRecX + (endRecX - startRecX) / 4, startRecY + 5, endRecX - (endRecX - startRecX) / 4, endRecY - 5);//圆圈的矩形范围
canvas.drawArc(mColorWheelRectangleS, -90, -180, false, mPaint);
mPaint.setColor(m30DayColor);
RectF mColorWheelRectangle = new RectF(startRecX + (endRecX - startRecX) / 4, startRecY + 5, endRecX - (endRecX - startRecX) / 4, endRecY - 5);//圆圈的矩形范围
canvas.drawArc(mColorWheelRectangle, -90, 180, false, mPaint);
} else {
mPaint.setColor(m0DayColor);
int px = DensityUtil.dip2px(getContext(), 12);
canvas.drawCircle((startRecX + endRecX) / 2, (startRecY + endRecY) / 2, px, mPaint);
}
mPaint.setColor(mDayColor);
canvas.drawText(dayString, startX, startY, mPaint);
}
}
@Override
public boolean onTouchEvent(MotionEvent event) {
return super.onTouchEvent(event);
}
/**
* 初始化列宽行高
*/
private void initSize(){
mColumnSize = getWidth() / NUM_COLUMNS;
mRowSize = getHeight() / NUM_ROWS;
}
/**
* 设置年月
* @param year
* @param month
*/
private void setSelectYearMonth(int year,int month,int day){
mSelYear = year;
mSelMonth = month;
mSelDay = day;
}
}
5.自定义日历带点击事件
public class MyMediaDayController extends View {
private static final int NUM_COLUMNS = 7;
private static final int NUM_ROWS = 6;
private int mColumnSize, mRowSize;//行宽、高
private int[][] daysString;//天数
private DisplayMetrics mDisplayMetrics;
private Paint mPaint;//画笔
private int mCurrYear, mCurrMonth, mCurrDay;//年月日
private int mSelYear, mSelMonth, mSelDay;//设置年月日
private int mDaySize = 14;//天数字体大小
private int mMonthDays;//一个月中有几天
private int mDayColor = Color.parseColor("#FFFFFF");//设置字体颜色
private int m15DayColor = Color.parseColor("#00BFFF");
private int m30DayColor = Color.parseColor("#FF7F50");
private int m0DayColor = Color.parseColor("#FF0000");
private int downX = 0, downY = 0;//点击事件坐标
private DateClick dateClick;
public MyMediaDayController(Context context, AttributeSet attrs) {
super(context, attrs);
mDisplayMetrics = getResources().getDisplayMetrics();
Calendar calendar = Calendar.getInstance();
mPaint = new Paint();
mPaint.setAntiAlias(true);
mCurrYear = calendar.get(Calendar.YEAR);
mCurrMonth = calendar.get(Calendar.MONTH) + 1;
mCurrDay = calendar.get(Calendar.DATE);
setSelectYearMonth(mCurrYear, mCurrMonth, 0);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
if (heightMode == MeasureSpec.AT_MOST) {
heightSize = mDisplayMetrics.densityDpi * 200;
}
if (widthMode == MeasureSpec.AT_MOST) {
widthSize = mDisplayMetrics.densityDpi * 300;
}
setMeasuredDimension(widthSize, heightSize);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
initSize();
daysString = new int[6][7];
mPaint.setTextSize(mDaySize * mDisplayMetrics.scaledDensity);
String dayString;
Calendar calendar = Calendar.getInstance();
mSelYear = calendar.get(Calendar.YEAR);
mSelMonth = calendar.get(Calendar.MONTH) + 1;
calendar.set(Calendar.YEAR, mSelYear);//先指定年份
calendar.set(Calendar.MONTH, mSelMonth - 1);//再指定月份 Java月份从0开始算
mMonthDays = calendar.getActualMaximum(Calendar.DATE);//获取指定年份中指定月份有几天
calendar.set(Calendar.DAY_OF_MONTH, 1); //获取指定年份月份中指定某天是星期几
int weekNumber = calendar.get(Calendar.DAY_OF_WEEK);//周几
for (int day = 0; day < mMonthDays; day++) {
dayString = (day + 1) + "";
int column = (day + weekNumber - 1) % 7;//一行中的第几个
int row = (day + weekNumber - 1) / 7;//第几列
daysString[row][column] = day + 1;
int startX = (int) (mColumnSize * column + (mColumnSize - mPaint.measureText(dayString)) / 2);
int startY = (int) (mRowSize * row + mRowSize / 2 - (mPaint.ascent() + mPaint.descent()) / 2);
//给日期绘制背景
int startRecX = mColumnSize * column;
int startRecY = mRowSize * row;
int endRecX = startRecX + mColumnSize;
int endRecY = startRecY + mRowSize;
if (mSelDay == (day + 1)){
mPaint.setColor(Color.parseColor("#FF83FA"));
int px = DensityUtil.dip2px(getContext(), 12);
canvas.drawCircle((startRecX + endRecX) / 2, (startRecY + endRecY) / 2, px, mPaint);
} else {
if (day > 15) {
mPaint.setColor(m15DayColor);
RectF mColorWheelRectangleS = new RectF(startRecX + (endRecX - startRecX) / 4, startRecY + 5, endRecX - (endRecX - startRecX) / 4, endRecY - 5);//圆圈的矩形范围
canvas.drawArc(mColorWheelRectangleS, -90, -180, false, mPaint);
mPaint.setColor(m30DayColor);
RectF mColorWheelRectangle = new RectF(startRecX + (endRecX - startRecX) / 4, startRecY + 5, endRecX - (endRecX - startRecX) / 4, endRecY - 5);//圆圈的矩形范围
canvas.drawArc(mColorWheelRectangle, -90, 180, false, mPaint);
} else {
mPaint.setColor(m0DayColor);
int px = DensityUtil.dip2px(getContext(), 12);
canvas.drawCircle((startRecX + endRecX) / 2, (startRecY + endRecY) / 2, px, mPaint);
}
}
mPaint.setColor(mDayColor);
canvas.drawText(dayString, startX, startY, mPaint);
}
}
@Override
public boolean onTouchEvent(MotionEvent event) {
int eventCode = event.getAction();
switch (eventCode) {
case MotionEvent.ACTION_DOWN:
downX = (int) event.getX();
downY = (int) event.getY();
break;
case MotionEvent.ACTION_MOVE:
break;
case MotionEvent.ACTION_UP:
int upX = (int) event.getX();
int upY = (int) event.getY();
if (Math.abs(upX - downX) < 10 && Math.abs(upY - downY) < 10) {//点击事件
performClick();
doClickAction((upX + downX) / 2, (upY + downY) / 2);
}
break;
}
return true;
}
/**
* 初始化列宽行高
*/
private void initSize() {
mColumnSize = getWidth() / NUM_COLUMNS;
mRowSize = getHeight() / NUM_ROWS;
}
/**
* 设置年月
*
* @param year
* @param month
*/
private void setSelectYearMonth(int year, int month, int day) {
mSelYear = year;
mSelMonth = month;
mSelDay = day;
}
/**
* 执行点击事件
*
* @param x
* @param y
*/
private void doClickAction(int x, int y) {
int row = y / mRowSize;
int column = x / mColumnSize;
Calendar calendar = Calendar.getInstance();
int myDay = calendar.get(Calendar.DATE);
//获取点击是第几天
setSelectYearMonth(mSelYear, mSelMonth, daysString[row][column]);
//刷新界面
invalidate();
if (dateClick != null) {
dateClick.onClickOnDate();
}
}
/**
* 设置日期的点击回调事件
* @author shiwei.deng
*
*/
public interface DateClick{
void onClickOnDate();
}
/**
* 设置日期点击事件
* @param dateClick
*/
public void setDateClick(DateClick dateClick) {
this.dateClick = dateClick;
}
}