Android精美日历控件CalendarView自定义使用完全解析

Android精美日历控件CalendarView自定义使用完全解析

2023年7月13日发(作者:)

Android精美⽇历控件CalendarView⾃定义使⽤完全解析项⽬github地址此框架采⽤组合的⽅式,各个模块互相独⽴,可⾃由采⽤各种提供的控件组合,完全⾃定义⾃⼰需要的UI,周视图和⽉视图可通过简单⾃定义任意⾃由绘制,不怕美⼯提需求下⾯教程将介绍如何实现3个API,⾃定义Canvas绘制⽇历CalendarView的优势:1、热插拔设计,根据不同的UI需求完全⾃定义UI,简单⼏步即可实现,⾃定义事件⽇历标记、颜⾊、农历等2、完全Canvas绘制,性能和速度都很不错,相⽐⼤多数基于GridView或RecyclerView实现的占⽤内存更低,启动速度更快3、⽀持收缩、展开、快速年⽉份选择等4、不要再问可不可以不显⽰其它⽉份的⽇期,可以,你可以任意配置到你喜欢为⽌;所以也不要问其它什么周末可不可以显⽰灰⾊,其它什么可不可以,这个控件真的可以,UI是万能绘制的5、简洁易懂的源码,易学习。Gradlecompile ':calendarview:3.2.9' calendarview 3.2.9 pom混淆proguard-rules-keepclasseswithmembers class * { public (t);}国际惯例,先上⼀个⾃定义效果图,结尾还有⼏个其它效果图,可⾃⼰⾃定义

各个类功能介绍CalendarLayout这是个辅助类,负责CalendarView的收缩控制功能,如果不需要收缩功能,⽆需使⽤它,⼀般使⽤教程如下 CalendarLayout apipublic void expand(); //展开public void shrink(); //收缩public boolean isExpand();//是否已经展开 CalendarView真正的⽇历类,可以⾃⾏通过attr配置完整attr CalendarView apipublic int getCurDay(); //今天public int getCurMonth(); //当前的⽉份public int getCurYear(); //今年public void showSelectLayout(final int year); //快速弹出年份选择⽉份public void closeSelectLayout(final int position); //关闭选择年份并跳转⽇期/*** 设置⽇期范围** @param minYear 最⼩年份* @param minYearMonth 最⼩年份对应⽉份* @param maxYear 最⼤⽉份* @param maxYearMonth 最⼤⽉份对应⽉份*/public void setRange(int minYear, int minYearMonth, int maxYear, int maxYearMonth)

public void setOnYearChangeListener(OnYearChangeListener listener);//年份切换事件public void setOnDateSelectedListener(OnDateSelectedListener listener);//⽇期选择事件public void setSchemeDate(List mSchemeDate);//标记⽇期public void update();//动态更新public Calendar getSelectedCalendar(); //获取选择的⽇期public void scrollToPre();//滚动到上⼀个⽉public void scrollToNext();//滚动到下⼀个⽉public void scrollToCalendar(int year, int month, int day);//滚动到指定⽇期/** * 设置背景⾊ * * @param monthLayoutBackground ⽉份卡⽚的背景⾊ * @param weekBackground 星期栏背景⾊ * @param lineBg 线的颜⾊ */public void setBackground(int monthLayoutBackground, int weekBackground, int lineBg)/** * 设置⽂本颜⾊ * * @param curMonthTextColor 当前⽉份字体颜⾊ * @param otherMonthColor 其它⽉份字体颜⾊ * @param lunarTextColor 农历字体颜⾊ */public void setTextColor(int curMonthTextColor,int otherMonthColor,int lunarTextColor)/** * 设置选择的效果 * * @param style 选中的style _FILL or _STROKE * @param selectedThemeColor 选中的标记颜⾊ * @param selectedTextColor 选中的字体颜⾊ */public void setSelectedColor(int style, int selectedThemeColor, int selectedTextColor)/** * 设置标记的⾊ * * @param style 标记的style _FILL or _STROKE * @param schemeColor 标记背景⾊ * @param schemeTextColor 标记字体颜⾊ */public void setSchemeColor(int style, int schemeColor, int schemeTextColor)/** * 设置背景⾊ * * @param yearViewBackground 年份卡⽚的背景⾊ * @param weekBackground 星期栏背景⾊ * @param lineBg 线的颜⾊*/public void setBackground(int yearViewBackground, int weekBackground, int lineBg)这个控件的特别之处就是它的UI是可以交给客户端⾃由绘制的,因此可以⾃由发挥想象⼒,绘制你需要的⽇历效果UI接下来介绍如何完全⾃定义⽇历,⾃定义⽇历需要同时⾃定义⽉视图和周视图,代码⼏乎⼀样,需要实现三个回调函数即可,如下:onDrawSelectedonDrawSchemeonDrawText/** * ⾸先继承⽉视图,假如我们想实现⾼仿魅族的⽇历 */public class MeiZuMonthView extends MonthView { /** * ⾃定义魅族标记的⽂本画笔 */ private Paint mTextPaint = new Paint(); /** * ⾃定义魅族标记的圆形背景 */ private Paint mSchemeBasicPaint = new Paint(); private float mRadio; private int mPadding; private float mSchemeBaseLine; public MeiZuMonthView(Context context) { super(context); tSize(dipToPx(context, 8)); or(0xffffffff); iAlias(true); eBoldText(true); iAlias(true); le(); tAlign(); eBoldText(true); mRadio = dipToPx(getContext(), 7); mPadding = dipToPx(getContext(), 4); trics metrics = tMetrics(); mSchemeBaseLine = mRadio - t + ( - ) / 2 + dipToPx(getContext(), 1); } /** * 绘制选中的⽇⼦ * @param canvas canvas * @param canvas canvas * @param calendar ⽇历⽇历calendar * @param x ⽇历Card x起点坐标 * @param y ⽇历Card y起点坐标 * @param hasScheme hasScheme ⾮标记的⽇期 */ @Override protected boolean onDrawSelected(Canvas canvas, Calendar calendar, int x, int y, boolean hasScheme) { le(); or(0x80cfcfcf); ct(x + mPadding, y + mPadding, x + mItemWidth - mPadding, y + mItemHeight - mPadding, mSelectedPaint); return true; } /** * 绘制标记的事件⽇⼦ * @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) { or(emeColor()); rcle(x + mItemWidth - mPadding - mRadio / 2, y + mPadding + mRadio, mRadio, mSchemeBasicPaint); xt(eme(), x + mItemWidth - mPadding - mRadio, y + mPadding + mSchemeBaseLine, mTextPaint); } /** * 绘制⽂本 * @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 (isSelected) {//优先绘制选择的 xt(f(()), cx, mTextBaseLine + top, mSelectTextPaint); xt(ar(), cx, mTextBaseLine + y + mItemHeight / 10, mSelectedLunarTextPaint); } else if (hasScheme) {//否则绘制具有标记的 xt(f(()), cx, mTextBaseLine + top, entMonth() ? mSchemeTextPaint : mOtherMonthTextPaint); xt(ar(), cx, mTextBaseLine + y + mItemHeight / 10, mCurMonthLunarTextPaint); } else {//最好绘制普通⽂本 xt(f(()), cx, mTextBaseLine + top, entDay() ? mCurDayTextPaint : entMonth() ? mCurMonthTextPaint : mOtherMonthTextPaint); xt(ar(), cx, mTextBaseLine + y + mItemHeight / 10, entDay() ? mCurDayLunarTextPaint : entMonth() ? mCurMonthLunarTextPaint : mOtherMonthLunarTextPaint); } } /** * dp转px * @return 返回true 则会继续绘制onDrawScheme,因为这⾥背景⾊不是是互斥的,所以返回true,返回false,则点击scheme标记的⽇⼦,则不继续绘制on * dp转px * * @param context context * @param dpValue dp * @return px */ private static int dipToPx(Context context, float dpValue) { final float scale = ources().getDisplayMetrics().density; return (int) (dpValue * scale + 0.5f); }}实现⾃定义周视图,周视图除了三个回调函数少了⼀个y参数,其它⼀样,因为周视图只有⼀⾏,所以可直接copyMonthView的代码,令y=0即可,如下public class MeizuWeekView extends WeekView { private Paint mTextPaint = new Paint(); private Paint mSchemeBasicPaint = new Paint(); private float mRadio; private int mPadding; private float mSchemeBaseLine; public MeizuWeekView(Context context) { super(context); tSize(dipToPx(context, 8)); or(0xffffffff); iAlias(true); eBoldText(true); iAlias(true); le(); tAlign(); or(0xffed5353); eBoldText(true); mRadio = dipToPx(getContext(), 7); mPadding = dipToPx(getContext(), 4); trics metrics = tMetrics(); mSchemeBaseLine = mRadio - t + ( - ) / 2 + dipToPx(getContext(), 1); } /** * * @param canvas canvas * @param calendar ⽇历⽇历calendar * @param x ⽇历Card x起点坐标 * @param hasScheme hasScheme ⾮标记的⽇期 * @return true 则绘制onDrawScheme,因为这⾥背景⾊不是是互斥的 */ @Override protected boolean onDrawSelected(Canvas canvas, Calendar calendar, int x, boolean hasScheme) { le(); or(0x80cfcfcf); ct(x + mPadding, mPadding, x + mItemWidth - mPadding, mItemHeight - mPadding, mSelectedPaint); return true; } @Override protected void onDrawScheme(Canvas canvas, Calendar calendar, int x) { or(emeColor()); rcle(x + mItemWidth - mPadding - mRadio / 2, mPadding + mRadio, mRadio, mSchemeBasicPaint); xt(eme(), x + mItemWidth - mPadding - mRadio, mPadding + mSchemeBaseLine, mTextPaint); xt(eme(), x + mItemWidth - mPadding - mRadio, mPadding + mSchemeBaseLine, mTextPaint); } @Override protected void onDrawText(Canvas canvas, Calendar calendar, int x, boolean hasScheme, boolean isSelected) { int cx = x + mItemWidth / 2; int top = -mItemHeight / 6; if (isSelected) { xt(f(()), cx, mTextBaseLine + top, mSelectTextPaint); xt(ar(), cx, mTextBaseLine + mItemHeight / 10, mSelectedLunarTextPaint); } else if (hasScheme) { xt(f(()), cx, mTextBaseLine + top, entMonth() ? mSchemeTextPaint : mOtherMonthTextPaint); xt(ar(), cx, mTextBaseLine + mItemHeight / 10, mCurMonthLunarTextPaint); } else { xt(f(()), cx, mTextBaseLine + top, entDay() ? mCurDayTextPaint : entMonth() ? mCurMonthTextPaint : mOtherMonthTextPaint); xt(ar(), cx, mTextBaseLine + mItemHeight / 10, entDay() ? mCurDayLunarTextPaint : entMonth() ? mCurMonthLunarTextPaint : mOtherMonthLunarTextPaint); } } /** * dp转px * * @param context context * @param dpValue dp * @return px */ private static int dipToPx(Context context, float dpValue) { final float scale = ources().getDisplayMetrics().density; return (int) (dpValue * scale + 0.5f); }}最后通过CalendarView两个attr配置class路径即可,是不是很像⾃定义Behavior?app:month_view="onthView"app:week_view="eekView"最后各种⾃定义UI效果⾃由欣赏,源码都在demo

建议clone APP Demo,⾥⾯作者实现了⼏种类型的风格,可以参考实现项⽬开源地址,⼀点贡献

发布者:admin,转转请注明出处:http://www.yc00.com/web/1689216834a222387.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信