2024年鸿蒙最新Android绘制日历_android 日历(2),面试题集锦

深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!


img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上鸿蒙开发知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

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

List lastMouthDay = CalendarUtil.getDays(tempY, tempM);



if (firstDayInMonth == 0) {//星期天
days.addAll(lastMouthDay.subList(lastMouthDay.size() - 7, lastMouthDay.size()));
} else {
days.addAll(lastMouthDay.subList(lastMouthDay.size() - firstDayInMonth, lastMouthDay.size()));
}


先获取上个月的天数,然后获取倒数几个, `days`用来存储需要绘制的日期。


接着加入当前月的日期(当前月全部装入days)



days.addAll(CalendarUtil.getDays(showYear, showMonth));


最后计算出需要下一个月的日期,因为我们绘制6行,所以一共显示42天。当前days已经存储了上一个月和当前月的日期,`42-days.size`就是需要下一个月的前几天



List nextMouthDay = CalendarUtil.getDays(nextYear, nextMonth);
days.addAll(nextMouthDay.subList(0, 42 - days.size()));


到此,日期数据就准备好了。


### 绘制日历


绘制之前先初始化一些参数,比如每个日期的宽度,高度等信息



//item高度
rowHeight = (int) (getResources().getDisplayMetrics().density*60);
//item宽度
columnWidth = getWidth() / 7;


然后开始绘制



for (int i = 0; i < days.size(); i++) {
int day = days.get(i).getDay();
String dayText = String.valueOf(day);
column = (i) / 7;
raw = (i) % 7;
float textWidth = textPaint.measureText(dayText);
Rect rect = new Rect();
textPaint.getTextBounds(dayText, 0, dayText.length(), rect);
int textHeight = rect.bottom - rect.top;
float textX = (columnWidth * raw) + (columnWidth - textWidth) / 2;
float textY = (rowHeight * (column) + titleHeight) + (rowHeight + textHeight) / 2;
if (days.get(i).isCurrentDay()) {
//今天
textPaint.setColor(defaultColor);
bgPaint.setColor(Color.parseColor(“#f7e1df”));
RectF selectedRect = new RectF(columnWidth * raw, rowHeight * (column) + titleHeight,
columnWidth * (raw + 1), rowHeight * (column + 1) + titleHeight);
canvas.drawRoundRect(selectedRect, 10, 10, bgPaint);
} else if (days.get(i).getMouth() == showMonth) {
//本月日期
textPaint.setColor(defaultColor);
} else {
//上一个月和下一个月
textPaint.setColor(Color.GRAY);
}
canvas.drawText(dayText, textX, textY, textPaint);
}


为了区分显示,今天的日期背景用了粉色标记,当前月的日期字体用了黑色,而上一个月和下一个月用了灰色,效果如图。  
 ![](https://img-blog.csdnimg.cn/801e4ec255f44936a2e2d824030c6634.png)  
 此时我们还不清楚日历某一对应的是星期几,所以还需要绘制头部信息


### 绘制头部


头部信息绘制比较简单,直接一行绘制7个文字即可



for (int week = 0; week < 7; week++) {
textPaint.setColor(defaultColor);
String weekText = CalendarUtil.getWeekText(week);
Rect rect = new Rect();
textPaint.getTextBounds(weekText, 0, weekText.length(), rect);
int textY = (int) (titleHeight * 0 + titleHeight / 2 - (textPaint.ascent() + textPaint.descent()) / 2);
float textX = columnWidth * week + (columnWidth - textPaint.measureText(weekText)) / 2;
canvas.drawText(weekText, textX, textY, textPaint);
}


###  处理点击事件


现在我们的日历还是静态的,不能交互,我们需要处理点击事件



public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
downX = event.getX();
downY = event.getY();
break;
case MotionEvent.ACTION_MOVE:
break;
case MotionEvent.ACTION_UP:
float upX = event.getX();
float upY = event.getY();
touchIndexX = (int) (upX / columnWidth);
if (upY >= 0 && upY <= titleHeight) {
touchIndexY = 0;
} else {
touchIndexY = (int) ((upY - titleHeight) / rowHeight) + 1;
}
if (touchIndexX >= 0 && touchIndexX <= 7 && touchIndexY >= 1 && touchIndexY <= 6) {
if (onCalenderItemClickListener != null) {
Day touchDay = days.get((touchIndexY - 1) * 7 + touchIndexX);
onCalenderItemClickListener.onCalenderItemClick(touchDay);
}
invalidate();
}

        break;
}
return true;

}


重写onTouchEvent方法,在手指抬起的时候计算出按下的位置位于日历上的那一天,然后回调给外部并刷新重新绘制界面,我们需要修改下绘制日期的地方



if (raw == touchIndexX && (column + 1) == touchIndexY) {
bgPaint.setColor(Color.parseColor(“#222222”));
textPaint.setColor(Color.WHITE);
RectF selectedRect = new RectF(columnWidth * touchIndexX, rowHeight * (touchIndexY - 1) + titleHeight,
columnWidth * (touchIndexX + 1), rowHeight * (touchIndexY) + titleHeight);
canvas.drawRoundRect(selectedRect, 10, 10, bgPaint);
touchIndexX = -1;
touchIndexY = -1;
}
//绘制文字之前先加上面逻辑
canvas.drawText(dayText, textX, textY, textPaint);


此时,日历就可以交互了,点击选中的日期背景黑色高亮


###  日程信息添加


最后在绘制日期的时候,我们还需要添加日程信息。那些天具有日程信息需要从外部传入。



public void setHaveThingsDay(List haveThingsDay) {
needRequestNet = false;
this.haveThingsDay = haveThingsDay;
invalidate();
}


然后再绘制的时候,遍历需要绘制的日历,查看是否在haveThingsDay中



if (haveThingsDay != null) {
for (int i = 0; i < days.size(); i++) {
for (int j = 0; j < haveThingsDay.size(); j++) {
if(days.get(i).getYear() == haveThingsDay.get(j).getYear()

img
img

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

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

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

如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**

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

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值