Android开源的精美日历控件,热插拔设计的万能自定义UI,阿里P7大牛整理




XML用法

如果需要在日历控件下方使用其它控件,使用CalendarLayout控件即可,calendar_content_view_id为其它控件的id,支持任意控件,如RecyclerView、ListView。CalendarView的calendar_card_view为任意自定义实现的日历绘制控件路径。

<com.haibin.calendarview.CalendarLayout
android: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.CalendarView
android: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” />



</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,然后实现onDrawSelected、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 非标记的日期
    */
    @Override
    protected 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起点坐标
    */
    @Override
    protected 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 是否选中
    */
    @Override
    protected 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);
}
}

/**

最后

对于很多初中级Android工程师而言,想要提升技能,往往是自己摸索成长,不成体系的学习效果低效漫长且无助。整理的这些架构技术希望对Android开发的朋友们有所参考以及少走弯路,本文的重点是你有没有收获与成长,其余的都不重要,希望读者们能谨记这一点。

同时我经过多年的收藏目前也算收集到了一套完整的学习资料以及高清详细的Android架构进阶学习导图及笔记免费分享给大家,希望对想成为架构师的朋友有一定的参考和帮助。

下面是部分资料截图,诚意满满:特别适合有开发经验的Android程序员们学习。

资料免费领取方式:点击我的GitHub~

不论遇到什么困难,都不应该成为我们放弃的理由!

😕/github.com/a120464/Android-P7/blob/master/Android%E5%BC%80%E5%8F%91%E4%B8%8D%E4%BC%9A%E8%BF%99%E4%BA%9B%EF%BC%9F%E5%A6%82%E4%BD%95%E9%9D%A2%E8%AF%95%E6%8B%BF%E9%AB%98%E8%96%AA%EF%BC%81.md)~**

不论遇到什么困难,都不应该成为我们放弃的理由!

如果你看到了这里,觉得文章写得不错就给个赞呗?如果你觉得那里值得改进的,请给我留言,一定会认真查询,修正不足,谢谢。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值