Android 开源的精美日历控件,热插拔设计的万能自定义 UI
<com.haibin.calendarview.CalendarLayoutandroid:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"android:background="#fff"app:calendar_content_view_id="@+id/linearView">
<com.haibin.calendarview.CalendarViewandroid:id="@+id/calendarView"android:layout_width="match_parent"android:layout_height="wrap_content"android:background="#fff"app:current_month_text_color="#333333"app:current_month_lunar_text_color="#CFCFCF"app:min_year="2004"app:other_month_text_color="#e1e1e1"app:scheme_text_color="#333"app:scheme_theme_color="#128c4b"app:selected_lunar_text_color="#CFCFCF"app:calendar_card_view="com.haibin.calendarviewproject.meizu.MeiZuCalendarCardView"app:selected_text_color="#333"app:selected_theme_color="#108cd4"app:week_background="#fff"app:week_text_color="#111" />
<LinearLayoutandroid:id="@+id/linearView"android:layout_width="match_parent"android:layout_height="match_parent"android:background="@color/content_background"android:clickable="true"android:orientation="vertical"tools:ignore="KeyboardInaccessibleWidget"/></LinearLayout></com.haibin.calendarview.CalendarLayout>
熟悉一下这几个简单的特性,看看日历内容界面的绘制 BaseCalendarCardView,根据需求实现以下部分方法即可
/**
开始绘制前的回调钩子,这里做一些初始化的操作,每次绘制只调用一次,性能高效
没有需要可忽略不实现
例如:
1、需要绘制圆形标记事件背景,可以在这里计算半径
2、绘制矩形选中效果,也可以在这里计算矩形宽和高*/protected void onPreviewHook() {// TODO: 2017/11/16}
/**
循环绘制开始的回调,不需要可忽略
绘制每个日历项的循环,用来计算 baseLine、圆心坐标等都可以在这里实现
@param x 日历 Card x 起点坐标
@param y 日历 Card y 起点坐标*/protected void onLoopStart(int x, int y) {// TODO: 2017/11/16}
/**
绘制选中的日期
@param canvas canvas
@param calendar 日历日历 calendar
@param x 日历 Card x 起点坐标
@param y 日历 Card y 起点坐标
@param hasScheme hasScheme 非标记的日期*/protected abstract void onDrawSelected(Canvas canvas, Calendar calendar, int x, int y, boolean hasScheme);
/**
绘制标记的日期 UI
@param canvas canvas
@param calendar 日历 calendar
@param x 日历 Card x 起点坐标
@param y 日历 Card y 起点坐标*/protected abstract void onDrawScheme(Canvas canvas, Calendar calendar, int x, int y);
/**
绘制日历文本
@param canvas canvas
@param calendar 日历 calendar
@param x 日历 Card x 起点坐标
@param y 日历 Card y 起点坐标
@param hasScheme 是否是标记的日期
@param isSelected 是否选中*/protected abstract void onDrawText(Canvas canvas, Calendar calendar, int x, int y, boolean hasScheme, boolean isSelected);
**举个例子:如果你的需求是类似魅族日历的 UI,那么第一步,继承 BaseCalendarCardView,然后实现 onDrawSe
lected、onDrawScheme、onDrawText 三个回调函数即可**
public class MeiZuCalendarCardView extends BaseCalendarCardView {
private Paint mTextPaint = new Paint();private Paint mSchemeBasicPaint = new Paint();private float mRadio;private int mPadding;private float mSchemeBaseLine;
public MeiZuCalendarCardView(Context context) {super(context);
mTextPaint.setTextSize(dipToPx(context, 8));mTextPaint.setColor(0xff111111);mTextPaint.setAntiAlias(true);mTextPaint.setFakeBoldText(true);
mSchemeBasicPaint.setAntiAlias(true);mSchemeBasicPaint.setStyle(Paint.Style.FILL);mSchemeBasicPaint.setTextAlign(Paint.Align.CENTER);mSchemeBasicPaint.setColor(0xffed5353);mSchemeBasicPaint.setFakeBoldText(true);mRadio = dipToPx(getContext(), 7);mPadding = dipToPx(getContext(), 4);Paint.FontMetrics metrics = mSchemeBasicPaint.getFontMetrics();mSchemeBaseLine = mRadio - metrics.descent + (metrics.bottom - metrics.top) / 2 + dipToPx(getContext(), 1);
}
/**
绘制选中的日期
@param canvas canvas
@param calendar 日历日历 calendar
@param x 日历 Card x 起点坐标
@param y 日历 Card y 起点坐标
@param hasScheme hasScheme 非标记的日期*/@Overrideprotected void onDrawSelected(Canvas canvas, Calendar calendar, int x, int y, boolean hasScheme) {mSelectedPaint.setStyle(Paint.Style.FILL);mSelectedPaint.setColor(0x80cfcfcf);canvas.drawRect(x + mPadding, y + mPadding, x + mItemWidth - mPadding, y + mItemHeight - mPadding, mSelectedPaint);}
/**
绘制标记的日期 UI 这里魅族界面不需要绘制多彩风格,忽略即可
@param canvas canvas
@param calendar 日历 calendar
@param x 日历 Card x 起点坐标
@param y 日历 Card y 起点坐标*/@Overrideprotected void onDrawScheme(Canvas canvas, Calendar calendar, int x, int y) {
}
/**
绘制日历文本
@param canvas canvas
@param calendar 日历 calendar
@param x 日历 Card x 起点坐标
@param y 日历 Card y 起点坐标
@param hasScheme 是否是标记的日期
@param isSelected 是否选中*/@Overrideprotected void onDrawText(Canvas canvas, Calendar calendar, int x, int y, boolean hasScheme, boolean isSelected) {int cx = x + mItemWidth / 2;int top = y - mItemHeight / 6;if (hasScheme) {//绘制日期 canvas.drawText(String.valueOf(calendar.getDay()), cx, mTextBaseLine + top,calendar.isCurrentDay() ? mCurDayTextPaint :calendar.isCurrentMonth() ? mSchemeTextPaint : mOtherMonthTextPaint);//绘制农历 canvas.drawText(calendar.getLunar(), cx, mTextBaseLine + y + mItemHeight / 10, mCurMonthLunarTextPaint);mTextPaint.setColor(Color.WHITE);mSchemeBasicPaint.setColor(calendar.getSchemeColor());//绘制圆圈 canvas.drawCircle(x + mItemWidth - mPadding - mRadio / 2, y + mPadding + mRadio, mRadio, mSchemeBasicPaint);//绘制事件文本 canvas.drawText(calendar.getScheme(), x + mItemWidth - mPadding - mRadio, y + mPadding + mSchemeBaseLine, mTextPaint);
} else {canvas.drawText(String.valueOf(calendar.getDay()), cx, mTextBaseLine + top,calendar.isCurrentDay() ? mCurDayTextPaint :calendar.isCurrentMonth() ? mCurMonthTextPaint : mOtherMonthTextPaint);canvas.drawText(calendar.getLunar(), cx, mTextBaseLine + y + mItemHeight / 10, mCurMonthLunarTextPaint);}}
/**
dp 转 px
@param context context
@param dpValue dp
@return px*/private static int dipToPx(Context context, float dpValue) {final float scale = context.getResources().getDisplayMetrics().density;return (int) (dpValue * scale + 0.5f);}}
评论