最近项目中需要用到日历控件,1.需要给已经记录的日期添加圆环标记2.给当天日期添加背景3.给周末日期更改颜色4.日历添加农历,需求如上图所示:
GitHub的material-calendarview star较高,而且项目最贴近以上需求
MaterialCalendarView项目开源地址:
https://github.com/prolificinteractive/material-calendarview
集成清单
1.添加compile'com.prolificinteractive:material-calendarview:1.4.2'
2.添加日历控件到布局中
功能展示
一.基础的功能和事件这里不做描述,可以到官方的demo中细看,下面贴出基础设置的xml和代码:
calendarView = (MaterialCalendarView) findViewById(R.id.calendar_calendarView);
year = TimeUtils.date2String(date, "yyyy");
month = TimeUtils.date2String(date, "MM");
//设置当前时间
calendarView.setCurrentDate(date);
calendarView
.state()
.edit()
//设置一周的第一天是周日还是周一
.setFirstDayOfWeek(Calendar.SUNDAY)
//设置日期范围
.setMinimumDate(CalendarDay.from(Integer.valueOf(year), Integer.parseInt(month) - 1, 1))
.setMaximumDate(CalendarDay.from(Integer.valueOf(year), Integer.parseInt(month) - 1, 31))
.setCalendarDisplayMode(CalendarMode.MONTHS)
.commit();
//设置周的文本
calendarView.setWeekDayLabels(new String[]{"日", "一", "二", "三", "四", "五", "六"});
//设置年月的title
calendarView.setTitleFormatter(new TitleFormatter() {
@Override
public CharSequence format(CalendarDay day) {
StringBuffer buffer = new StringBuffer();
int yearOne = day.getYear();
int monthOne = day.getMonth() + 1;
buffer.append(yearOne).append("年").append(monthOne).append("月");
return buffer;
}
});
//添加修饰
calendarView.addDecorators(new HighlightWeekendsDecorator(), new SameDayDecorator(), new LunarDecorator(year, month), new WorkdayDecorator());
//日期点击事件
calendarView.setOnDateChangedListener(this);
二.下面介绍MaterialCalendarView的强大自定义功能,addDecorators给特定日期添加特殊标记,首先要实现DayViewDecorator ,里面的shouldDecorate方法用于判断是否要对指定日期进行修饰,返回值boolean,decorate方法用于设置样式,里面运用了之前根本不了解的各种Span。
1.给周末日期设置特殊字体颜色:
/**
* 作者:徐敏敏 on 2016/12/20 0020 14:27
* 邮箱:15067596185@163.com
*/
public class HighlightWeekendsDecorator implements DayViewDecorator {
private final Calendar calendar = Calendar.getInstance();
@Override
public boolean shouldDecorate(CalendarDay day) {
day.copyTo(calendar);
int weekDay = calendar.get(Calendar.DAY_OF_WEEK);
return weekDay == Calendar.SATURDAY || weekDay == Calendar.SUNDAY;
}
@Override
public void decorate(DayViewFacade view) {
view.addSpan(new ForegroundColorSpan(Color.parseColor("#fd755c")));
}
}
2.给日历当天进行圆背景修饰:
/**
* 作者:徐敏敏 on 2016/12/20 0020 14:27
* 邮箱:15067596185@163.com
*/
public class SameDayDecorator implements DayViewDecorator {
@Override
public boolean shouldDecorate(CalendarDay day) {
Date date = new Date();
String dateStr = TimeUtils.date2String(date, "yyyy-MM-dd");
Date parse = TimeUtils.string2Date(dateStr, "yyyy-MM-dd");
if (day.getDate().equals(parse)) {
return true;
}
return false;
}
@Override
public void decorate(DayViewFacade view) {
view.addSpan(new CircleBackGroundSpan());
}
}
/**
* 作者:徐敏敏 on 2016/12/20 0020 14:27
* 邮箱:15067596185@163.com
*/
public class CircleBackGroundSpan implements LineBackgroundSpan {
@Override
public void drawBackground(Canvas c, Paint p, int left, int right, int top, int baseline, int bottom, CharSequence text, int start, int end, int lnum) {
Paint paint = new Paint();
paint.setColor(Color.parseColor("#def0ef"));
c.drawCircle((right - left) / 2, (bottom - top) / 2 + dip2px(4), dip2px(18), paint);
}
}
3.给日历每一天下方添加农历字体:
/**
* 作者:徐敏敏 on 2016/12/20 0020 14:27
* 邮箱:15067596185@163.com
*/
public class LunarDecorator implements DayViewDecorator {
private String year;
private String month;
public LunarDecorator(String year, String month) {
this.year = year;
this.month = month;
}
@Override
public boolean shouldDecorate(CalendarDay day) {
return true;
}
@Override
public void decorate(DayViewFacade view) {
view.addSpan(new LunarSpan(year,month));
}
}
/**
* 作者:徐敏敏 on 2016/12/20 0020 14:27
* 邮箱:15067596185@163.com
*/
public class LunarSpan implements LineBackgroundSpan {
private String year;
private String month;
public LunarSpan(String year, String month) {
this.year = year;
this.month = month;
}
@Override
public void drawBackground(Canvas c, Paint p, int left, int right, int top, int baseline, int bottom, CharSequence text, int start, int end, int lnum) {
StringBuffer buffer = new StringBuffer();
buffer.append(year).append("-").append(month).append("-").append(text);
Date parse = TimeUtils.string2Date(buffer.toString(), "yyyy-MM-dd");
Calendar calendar = Calendar.getInstance();
calendar.setTime(parse);
Lunar lunar = new Lunar(calendar);
String chinaDayString = lunar.getChinaDayString();
Paint paint = new Paint();
paint.setTextSize(dip2px(10));
paint.setColor(Color.parseColor("#cccccc"));
c.drawText(chinaDayString, (right - left) / 2 - dip2px(10), (bottom - top) / 2 + dip2px(17), paint);
}
}
4.对特定日期增加圆环修饰:
/**
* 作者:徐敏敏 on 2016/12/20 0020 14:27
* 邮箱:15067596185@163.com
*/
public class EventDecorator implements DayViewDecorator {
private List<Date> dates;
public EventDecorator(List<Date> dates) {
this.dates = dates;
}
@Override
public boolean shouldDecorate(CalendarDay day) {
return dates.contains(day.getDate());
}
@Override
public void decorate(DayViewFacade view) {
view.addSpan(new AnnulusSpan());
}
}
/**
* 作者:徐敏敏 on 2016/12/20 0020 14:27
* 邮箱:15067596185@163.com
*/
public class AnnulusSpan implements LineBackgroundSpan {
@Override
public void drawBackground(Canvas c, Paint p, int left, int right, int top, int baseline, int bottom, CharSequence text, int start, int end, int lnum) {
Paint paint = new Paint();
paint.setAntiAlias(true); //消除锯齿
paint.setStyle(Paint.Style.STROKE);//绘制空心圆或 空心矩形
int ringWidth = dip2px(1);//圆环宽度
//绘制圆环
paint.setColor(Color.parseColor("#00bcbe"));
paint.setStrokeWidth(ringWidth);
c.drawCircle((right - left) / 2, (bottom - top) / 2 + dip2px(4), dip2px(18), paint);
}
}