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

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

项目开源地址

https://github.com/huanghaibin-dev/CalendarView

CalendarView的优势:

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

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

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

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

先看看控件的attr

<declare-styleable name="CalendarView"><attr name="calendar_card_view" format="color" /> <!--热插拔自定义类路径--><attr name="week_background" format="color" /> <!--星期栏的背景--><attr name="week_text_color" format="color" /> <!--星期栏文本颜色--><attr name="current_day_text_color" format="color" /> <!--今天的文本颜色--><attr name="day_text_size" format="string" /> <!--天数文本大小--><attr name="lunar_text_size" format="string" /> <!--农历文本大小--><attr name="scheme_text" format="string" /> <!--标记文本--><attr name="scheme_text_color" format="color" /> <!--标记文本颜色--><attr name="scheme_month_text_color" format="color" /> <!--标记天数文本颜色--><attr name="scheme_lunar_text_color" format="color" /> <!--标记农历文本颜色--><attr name="scheme_theme_color" format="color" /> <!--标记的颜色--><attr name="selected_theme_color" format="color" /> <!--选中颜色--><attr name="selected_text_color" format="color" /> <!--选中文本颜色--><attr name="selected_lunar_text_color" format="color" /> <!--选中农历文本颜色--><attr name="current_month_text_color" format="color" /> <!--当前月份的字体颜色--><attr name="other_month_text_color" format="color" /> <!--其它月份的字体颜色--><attr name="current_month_lunar_text_color" format="color" /> <!--当前月份农历节假日颜色--><attr name="other_month_lunar_text_color" format="color" /> <!--其它月份农历节假日颜色--><attr name="min_year" format="integer" />  <!--最小年份1900--><attr name="max_year" format="integer" /> <!--最大年份2099--></declare-styleable>复制代码

XML用法

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

<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,然后实现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 非标记的日期*/@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);}
}复制代码

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

效果预览

高仿魅族日历界面

快速年月份选择

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

多彩风格界面

下标风格界面

简单没有农历界面

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

项目开源地址

https://github.com/huanghaibin-dev/CalendarView

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

Android开源的精美日历控件,热插拔设计的万能自定义UI相关推荐

  1. android+高仿+日历,Android开源的精美日历控件,热插拔设计的万能自定义UI

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

  2. Android开源的精美日历控件,热插拔设计的万能自定义UI,看完直接怼产品经理

    <attr name="current_month_text_color" format="color" /> <!--当前月份的字体颜色-- ...

  3. Android开源的精美日历控件,热插拔设计的万能自定义UI,flutter调用原生sdk

    XML用法 如果需要在日历控件下方使用其它控件,使用CalendarLayout控件即可,calendar_content_view_id为其它控件的id,支持任意控件,如RecyclerView.L ...

  4. Android开源的精美日历控件,热插拔设计的万能自定义UI,你值得拥有

    XML用法 如果需要在日历控件下方使用其它控件,使用CalendarLayout控件即可,calendar_content_view_id为其它控件的id,支持任意控件,如RecyclerView.L ...

  5. 开源一个ReactNative日历控件

    项目地址: react-native-slideable-calendar-strip 演示地址: Calendar-Strip.mp4 为何要再实现一个日历控件 已经有了react-native-c ...

  6. android自定义选年控件,Android精美日历控件CalendarView自定义使用完全解析

    项目github地址 此框架采用组合的方式,各个模块互相独立,可自由采用各种提供的控件组合,完全自定义自己需要的UI,周视图和月视图可通过简单自定义任意自由绘制,不怕美工提需求!!!下面教程将介绍如何 ...

  7. C#自定义checkBox开关按钮控件,设计漂亮美观的UI按钮

    第一步: 先准备开关按钮要使用到的背景图片,一张是开启的,一张是关闭的,如下图:       一共有6种款式,大家也可以全部加进去 图标素材下载地址: https://download.csdn.ne ...

  8. android程序日历layout,Android使用GridLayout绘制自定义日历控件

    效果图 思路:就是先设置Gridlayout的行列数,然后往里面放置一定数目的自定义日历按钮控件,最后实现日历逻辑就可以了. 步骤: 第一步:自定义日历控件(初步) 第二步:实现自定义单个日期按钮控件 ...

  9. 9 款样式华丽的 jQuery 日期选择和日历控件

    现在的网页应用越来越丰富,我们在网页中填写日期和时间已经再也不用手动输入了,而是使用各种各样的日期时间选择控件,大部分样式华丽的日期选择和日历控件都是基于jQuery和HTML5的,比如今天要分享的这 ...

最新文章

  1. 独家 | 人工神经网络中发现了人类大脑拥有的多模态神经元(附链接)
  2. 【java的多态性】
  3. selenium-webdriver(python) (十六) --unittest 框架
  4. 数据中心进行数字化转型的2019年
  5. (一)easyUI之树形网络
  6. WP7有约(六):AppBarUtils使用指南
  7. Arcgis javascript那些事儿(十七)——地理编码服务的发布与使用
  8. 4x4矩阵键盘工作原理及扫描程序_4*4 矩阵键盘工作原理
  9. android 2k屏分辨率是多少,为什么大多数手机屏幕都用1080P分辨率而不用2K?
  10. [转]Apache Ignite——新一代数据库缓存系统
  11. 【贪玩巴斯】带你一起攻克英语语法长难句—— 第三章——名词(短语)和名词性从句{主语、宾语、表语和同位语}全解 ——2022年2月6日-16日
  12. Android 开发第七弹:简易时钟(秒表)
  13. 指定的文件夹没有包含设备的兼容软件驱动程序...请确认它是为用于基于X64的系统的Windows设计的
  14. Ionic入门学习(一)
  15. 《数据中台架构:企业数据化最佳实践》:感受数据中台建设五步法
  16. PCI总线---深入理解PCI总线
  17. Verilog实现按键计数器
  18. Reac生命周期钩子之getSnapshotBeforeUpdate
  19. Internet协议---UDP(一)
  20. Word转Chm 在线转换应用

热门文章

  1. 2022年高处安装、维护、拆除报名考试及高处安装、维护、拆除新版试题
  2. 北京理工大学计算机保研面试,保研之旅2:北京理工大学雷达所面试
  3. windows上在python玩耍深度学习资源合集
  4. Java实现ATM机
  5. logstash之grok正则表达式语法
  6. Unable to negotiate with 120.26.106.212 port 22: no matching host key type f
  7. javascript实现按频次排序
  8. last_ack状态及rst标记
  9. 蓝桥杯 试题 算法训练 筛选号码 Java
  10. python常用常用函数