博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Android开源的精美日历控件,热插拔设计的万能自定义UI
阅读量:5828 次
发布时间:2019-06-18

本文共 6482 字,大约阅读时间需要 21 分钟。

UI框架应该逻辑与界面实现分离,该日历控件使用了热插拔的设计 ,简单几步即可实现你需要的UI效果,热插拔的思想是你提供你的实现,我提供我的插座接口,与自定义Behavior是一样的思想。

听说第一页无效果图就看不下去了?先上个高仿魅族日历界面

     

项目开源地址

CalendarView的优势:

1、热插拔设计,根据不同的UI需求完全自定义UI,简单几步即可实现,自定义事件日历标记、颜色、农历等

2、完全Canvas绘制,性能和速度都很不错,相比大多数基于GridView或RecyclerView实现的占用内存更低,启动速度更快

3、支持收缩、展开、快速年月份选择等

4、简洁易懂的源码,易学习。

先看看控件的attr

复制代码

XML用法

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

复制代码

熟悉一下这几个简单的特性,看看日历内容界面的绘制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);        }    }    /**     * 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);    }}复制代码

第二步:使用方法、app:calendar_card_view="xxx.xx.MeiZuCalendarCardView"

效果预览

高仿魅族日历界面

     

快速年月份选择

其它作者实现的几个UI效果预览,简单源码都在demo可以看到

多彩风格界面

     

下标风格界面

     

简单没有农历界面

     

更多参考用法移步APP Demo,里面作者实现了几种类型的风格,可以参考实现

项目开源地址

如果觉得源码可以请给个star,源码注释完善,简单易懂,容易学习。

转载地址:http://nnodx.baihongyu.com/

你可能感兴趣的文章
32、SpringBoot-整合Dubbo
查看>>
python面向对象基础
查看>>
HDU 2044 一只小蜜蜂(递归)
查看>>
docker 下 安装rancher 笔记
查看>>
spring两大核心对象IOC和AOP(新手理解)
查看>>
数据分析相关
查看>>
Python LDAP中的时间戳转换为Linux下时间
查看>>
微信小程序蓝牙连接小票打印机
查看>>
环境错误2
查看>>
C++_了解虚函数的概念
查看>>
全新jmeter视频已经上架
查看>>
Windows 8下如何删除无线配置文件
查看>>
oracle系列(五)高级DBA必知的Oracle的备份与恢复(全录收集)
查看>>
hp 服务器通过串口重定向功能的使用
查看>>
国外10大IT网站和博客网站
查看>>
android第十一期 - SmoothSwitchLibrary仿IOS切换Activity动画效果
查看>>
zabbix 批量web url监控
查看>>
MongoDB CookBook读书笔记之导入导出
查看>>
shell如何快速锁定所有账号
查看>>
HTML 5实现的手机摇一摇
查看>>