转发链接:https://blog.csdn.net/huanghaibin_dev/article/details/79040147
github中文文档:https://github.com/huanghaibin-dev/CalendarView/blob/master/QUESTION_ZH.md
github地址:https://github.com/huanghaibin-dev/CalendarView
由于该插件比较灵活,可以自定义View来实现日历功能,毫不犹豫地就采用该插件来实现项目的日历功能,项目需要实现的效果:

接入插件步骤:
一、在app的build.gradle中添加依赖:
implementation 'com.haibin:calendarview:3.6.6'
二、布局文件
<com.haibin.calendarview.CalendarLayout
android:id="@+id/calendarLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#fff"
android:orientation="vertical"
app:calendar_content_view_id="@+id/recyclerView"
app:calendar_show_mode="only_month_view">
<com.haibin.calendarview.CalendarView
android:id="@+id/calendarView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#fff"
android:clickable="false"
app:calendar_padding="10dp"
app:current_month_lunar_text_color="@color/fontColor_05"
app:current_month_text_color="#333333"
app:month_view="com.utils.colorful.ColorfulMonthView"
app:month_view_show_mode="mode_fix"
app:other_month_lunar_text_color="@color/White"
app:other_month_text_color="@color/fontColor_05"
app:scheme_text_color="#fff"
app:scheme_theme_color="@color/colorPrimary"
app:selected_lunar_text_color="@color/White"
app:selected_text_color="@color/White"
app:week_start_with="mon"
app:week_text_color="@color/fontColor_05"
app:week_text_size="16sp"
app:week_view="com.utils.meizu.MeizuWeekView"
app:year_view_day_text_color="@color/fontColor_07"
app:year_view_day_text_size="7sp"
app:year_view_month_text_color="#ff0000"
app:year_view_month_text_size="20sp"
app:year_view_scheme_color="#f17706"
app:year_view_select_text_color="#fff"
app:year_view_week_height="12dp"
app:year_view_week_text_color="@color/fontColor_05"
app:year_view_week_text_size="6sp" />
</com.haibin.calendarview.CalendarLayout>
加入该段代码便可以实现一般的日历功能,需要定制日历样式的话就继承周、月、年视图来自定义视图样式。
三、继承MonthView、WeekView、YearView类
由于只需要展示该月份的日历视图,故只继承了MonthView类(参考了demo的ColorfulWeekView类)
public class ColorfulWeekView extends WeekView {
private int mRadius;
public ColorfulWeekView(Context context) {
super(context);
//兼容硬件加速无效的代码
setLayerType(View.LAYER_TYPE_SOFTWARE, mSelectedPaint);
//4.0以上硬件加速会导致无效
mSelectedPaint.setMaskFilter(new BlurMaskFilter(30, BlurMaskFilter.Blur.SOLID));
setLayerType(View.LAYER_TYPE_SOFTWARE, mSchemePaint);
mSchemePaint.setMaskFilter(new BlurMaskFilter(30, BlurMaskFilter.Blur.SOLID));
}
@Override
protected void onPreviewHook() {
mRadius = Math.min(mItemWidth, mItemHeight) / 5 * 2;
}
/**
* 如果需要点击Scheme没有效果,则return true
*
* @param canvas canvas
* @param calendar 日历日历calendar
* @param x 日历Card x起点坐标
* @param hasScheme hasScheme 非标记的日期
* @return false 则不绘制onDrawScheme,因为这里背景色是互斥的
*/
@Override
protected boolean onDrawSelected(Canvas canvas, Calendar calendar, int x, boolean hasScheme) {
int cx = x + mItemWidth / 2;
int cy = mItemHeight / 2;
canvas.drawCircle(cx, cy, mRadius, mSelectedPaint);
return true;
}
@Override
protected void onDrawScheme(Canvas canvas, Calendar calendar, int x) {
int cx = x + mItemWidth / 2;
int cy = mItemHeight / 2;
canvas.drawCircle(cx, cy, mRadius, mSchemePaint);
}
@SuppressWarnings("IntegerDivisionInFloatingPointContext")
@Override
protected void onDrawText(Canvas canvas, Calendar calendar, int x, boolean hasScheme, boolean isSelected) {
int cx = x + mItemWidth / 2;
int top = -mItemHeight / 8;
if (isSelected) {
canvas.drawText(String.valueOf(calendar.getDay()), cx, mTextBaseLine + top,
calendar.isCurrentDay() ? mCurDayTextPaint : mSelectTextPaint);
canvas.drawText(calendar.getLunar(), cx, mTextBaseLine + mItemHeight / 10,
calendar.isCurrentDay() ? mCurDayLunarTextPaint : mSelectedLunarTextPaint);
} else if (hasScheme) {
canvas.drawText(String.valueOf(calendar.getDay()), cx, mTextBaseLine + top,
calendar.isCurrentDay() ? mCurDayTextPaint :
calendar.isCurrentMonth() ? mSchemeTextPaint : mSchemeTextPaint);
canvas.drawText(calendar.getLunar(), cx, mTextBaseLine + mItemHeight / 10, mSchemeLunarTextPaint);
} else {
canvas.drawText(String.valueOf(calendar.getDay()), cx, mTextBaseLine + top,
calendar.isCurrentDay() ? mCurDayTextPaint :
calendar.isCurrentMonth() ? mCurMonthTextPaint : mCurMonthTextPaint);
canvas.drawText(calendar.getLunar(), cx, mTextBaseLine + mItemHeight / 10,
calendar.isCurrentDay() ? mCurDayLunarTextPaint : mCurMonthLunarTextPaint);
}
}
}
四、在Activty中添加展示数据
核心代码:
protected void initData() {
int year = mCalendarView.getCurYear();
int month = mCalendarView.getCurMonth();
Map<String, Calendar> map = new HashMap<>();
for (int i = 1; i < 31; i++) {
if (i <= 7) {
map.put(getSchemeCalendar(year, month, i, getResources().getColor(R.color.colorPrimary), "假").toString(),
getSchemeCalendar(year, month, i, getResources().getColor(R.color.colorPrimary), "假"));
} else if (i <= 14) {
map.put(getSchemeCalendar(year, month, i, getResources().getColor(R.color.Green), "假").toString(),
getSchemeCalendar(year, month, i, getResources().getColor(R.color.Green), "假"));
} else if (i <= 21) {
map.put(getSchemeCalendar(year, month, i, getResources().getColor(R.color.YellowGreen), "假").toString(),
getSchemeCalendar(year, month, i, getResources().getColor(R.color.YellowGreen), "假"));
} else if (i <= 30) {
map.put(getSchemeCalendar(year, month, i, getResources().getColor(R.color.Yellow), "假").toString(),
getSchemeCalendar(year, month, i, getResources().getColor(R.color.Yellow), "假"));
}
}
//此方法在巨大的数据量上不影响遍历性能,推荐使用
mCalendarView.setSchemeDate(map);
mCalendarView.setMonthViewScrollable(false);
mCalendarView.setWeekViewScrollable(false);
//设置日期拦截事件
mCalendarView.setOnCalendarInterceptListener(new CalendarView.OnCalendarInterceptListener() {
@Override
public boolean onCalendarIntercept(Calendar calendar) {
//这里写拦截条件,返回true代表拦截,尽量以最高效的代码执行
return true;
}
@Override
public void onCalendarInterceptClick(Calendar calendar, boolean isClick) {
//todo 点击拦截的日期回调
}
});
mCalendarView.setClickable(false);
mCalendarView.setEnabled(false);
}
private Calendar getSchemeCalendar(int year, int month, int day, int color, String text) {
Calendar calendar = new Calendar();
calendar.setYear(year);
calendar.setMonth(month);
calendar.setDay(day);
calendar.setSchemeColor(color);//如果单独标记颜色、则会使用这个颜色
calendar.setScheme(text);
calendar.addScheme(new Calendar.Scheme());
calendar.addScheme(0xFF008800, "假");
calendar.addScheme(0xFF008800, "节");
return calendar;
}
五、运行效果

转载:https://blog.csdn.net/yusam07/article/details/101292622
查看评论