Android最全Android精美日历控件CalendarView自定义使用完全解析,2024年最新hashmap面试问题

学习分享

在当下这个信息共享的时代,很多资源都可以在网络上找到,只取决于你愿不愿意找或是找的方法对不对了

很多朋友不是没有资料,大多都是有几十上百个G,但是杂乱无章,不知道怎么看从哪看起,甚至是看后就忘

如果大家觉得自己在网上找的资料非常杂乱、不成体系的话,我也分享一套给大家,比较系统,我平常自己也会经常研读。

2021最新上万页的大厂面试真题

七大模块学习资料:如NDK模块开发、Android框架体系架构…

只有系统,有方向的学习,才能在段时间内迅速提高自己的技术。

这份体系学习笔记,适应人群:
第一,学习知识比较碎片化,没有合理的学习路线与进阶方向。
第二,开发几年,不知道如何进阶更进一步,比较迷茫。
第三,到了合适的年纪,后续不知道该如何发展,转型管理,还是加强技术研究。如果你有需要,我这里恰好有为什么,不来领取!说不定能改变你现在的状态呢!
由于文章内容比较多,篇幅不允许,部分未展示内容以截图方式展示 。

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化学习资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

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:max_year=“2020”
app:other_month_text_color=“#e1e1e1”
app:other_month_lunar_text_color=“#e1e1e1”
app:scheme_text=“假”
app:scheme_text_color=“#333”
app:scheme_theme_color=“#128c4b”
app:selected_lunar_text_color=“#CFCFCF”
app:month_view=“com.haibin.calendarviewproject.meizu.MeiZuMonthView”
app:week_view=“com.haibin.calendarviewproject.meizu.MeizuWeekView”
app:selected_text_color=“#333”
app:selected_theme_color=“#108cd4”
app:week_background=“#fff”
app:week_text_color=“#111”
app:year_view_day_text_color=“#333333”
app:year_view_day_text_size=“9sp”
app:year_view_month_text_color=“#ff0000”
app:year_view_month_text_size=“20sp”
app:year_view_scheme_color=“#f17706”/>

完整attr



























 

CalendarView api

public 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 CalendarCardView.STYLE_FILL or CalendarCardView.STYLE_STROKE
  • @param selectedThemeColor 选中的标记颜色
  • @param selectedTextColor 选中的字体颜色
    */
    public void setSelectedColor(int style, int selectedThemeColor, int selectedTextColor)

/**

  • 设置标记的色
  • @param style 标记的style CalendarCardView.STYLE_FILL or CalendarCardView.STYLE_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

接下来介绍如何完全自定义日历,自定义日历需要同时自定义月视图和周视图,代码几乎一样,需要实现三个回调函数即可,如下:

onDrawSelected
onDrawScheme
onDrawText

/**

  • 首先继承月视图,假如我们想实现高仿魅族的日历
    */

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);

mTextPaint.setTextSize(dipToPx(context, 8));
mTextPaint.setColor(0xffffffff);
mTextPaint.setAntiAlias(true);
mTextPaint.setFakeBoldText(true);

mSchemeBasicPaint.setAntiAlias(true);
mSchemeBasicPaint.setStyle(Paint.Style.FILL);
mSchemeBasicPaint.setTextAlign(Paint.Align.CENTER);
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 非标记的日期
  • @return 返回true 则会继续绘制onDrawScheme,因为这里背景色不是是互斥的,所以返回true,返回false,则点击scheme标记的日子,则不继续绘制onDrawScheme,自行选择即可
    */
    @Override
    protected boolean 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);
    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) {
    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);
}

/**

  • 绘制文本
  • @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) {//优先绘制选择的
canvas.drawText(String.valueOf(calendar.getDay()), cx, mTextBaseLine + top,
mSelectTextPaint);
canvas.drawText(calendar.getLunar(), cx, mTextBaseLine + y + mItemHeight / 10, mSelectedLunarTextPaint);
} else if (hasScheme) {//否则绘制具有标记的
canvas.drawText(String.valueOf(calendar.getDay()), cx, mTextBaseLine + top,
calendar.isCurrentMonth() ? mSchemeTextPaint : mOtherMonthTextPaint);

canvas.drawText(calendar.getLunar(), cx, mTextBaseLine + y + mItemHeight / 10, mCurMonthLunarTextPaint);
} 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,
calendar.isCurrentDay() ? mCurDayLunarTextPaint :
calendar.isCurrentMonth() ? mCurMonthLunarTextPaint : mOtherMonthLunarTextPaint);
}
}

/**

  • 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);
    }
    }
实现自定义周视图,周视图除了三个回调函数少了一个y参数,其它一样,因为周视图只有一行,所以可直接copy MonthView的代码,令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);

mTextPaint.setTextSize(dipToPx(context, 8));
mTextPaint.setColor(0xffffffff);
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);

尾声

如果你想成为一个优秀的 Android 开发人员,请集中精力,对基础和重要的事情做深度研究。

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

这里,笔者分享一份从架构哲学的层面来剖析的视频及资料给大家梳理了多年的架构经验,筹备近6个月最新录制的,相信这份视频能给你带来不一样的启发、收获。

Android进阶学习资料库

一共十个专题,包括了Android进阶所有学习资料,Android进阶视频,Flutter,java基础,kotlin,NDK模块,计算机网络,数据结构与算法,微信小程序,面试题解析,framework源码!

大厂面试真题

PS:之前因为秋招收集的二十套一二线互联网公司Android面试真题 (含BAT、小米、华为、美团、滴滴)和我自己整理Android复习笔记(包含Android基础知识点、Android扩展知识点、Android源码解析、设计模式汇总、Gradle知识点、常见算法题汇总。)

《2019-2021字节跳动Android面试历年真题解析》

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化学习资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

Gradle知识点、常见算法题汇总。)

[外链图片转存中…(img-PViC7zUE-1715191298988)]

《2019-2021字节跳动Android面试历年真题解析》

[外链图片转存中…(img-uCJj1c3M-1715191298988)]

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化学习资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

  • 29
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值