鸿蒙应用开发-- 打卡组件: 数据持久化,连续天数计算,UI组件,日历视图展示,打卡动画,以及时区处理,数据安全,性能优化
如果需要更复杂的日历组件,可以参考鸿蒙的 Calendar。
·
以下是基于鸿蒙(HarmonyOS)ArkUI(ETS)实现打卡组件的示例代码,包含打卡功能和已打卡天数的展示:
1. 基础打卡组件实现(含数据持久化)
import { Calendar } from '@ohos.application.DataAbility';
import { Preferences } from '@ohos.data.preferences';
@Entry
@Component
struct ClockInComponent {
// 打卡记录(存储格式:YYYY-MM-DD)
@State clockInDays: string[] = [];
// 连续打卡天数
@State consecutiveDays: number = 0;
// 初始化Preferences存储
private prefs: Preferences = await Preferences.getPreferences(getContext(this), 'ClockInData');
aboutToAppear() {
// 从本地存储加载打卡记录
this.prefs.get('clockInDays', []).then((data) => {
if (data) {
this.clockInDays = JSON.parse(data as string);
this.calculateConsecutiveDays();
}
});
}
// 计算连续打卡天数
private calculateConsecutiveDays() {
let count = 0;
const today = new Date();
for (let i = this.clockInDays.length - 1; i >= 0; i--) {
const date = new Date(this.clockInDays[i]);
if (this.isConsecutiveDate(today, date)) {
count++;
today.setDate(today.getDate() - 1);
} else {
break;
}
}
this.consecutiveDays = count;
}
// 判断两个日期是否连续
private isConsecutiveDate(date1: Date, date2: Date): boolean {
const diffTime = date1.getTime() - date2.getTime();
const diffDays = diffTime / (1000 * 3600 * 24);
return diffDays >= 1 && diffDays < 2;
}
// 执行打卡操作
async onClockIn() {
const today = new Date();
const todayStr = today.toISOString().split('T')[0]; // YYYY-MM-DD
if (!this.clockInDays.includes(todayStr)) {
this.clockInDays = [...this.clockInDays, todayStr];
await this.prefs.put('clockInDays', JSON.stringify(this.clockInDays));
await this.prefs.flush();
this.calculateConsecutiveDays();
}
}
build() {
Column() {
// 显示连续打卡天数
Text(`连续打卡 ${this.consecutiveDays} 天`)
.fontSize(20)
.margin(10)
// 打卡按钮
Button('点击打卡')
.width(150)
.height(40)
.onClick(() => this.onClockIn())
// 历史打卡日历
List({ space: 5 }) {
ForEach(this.clockInDays, (day: string) => {
ListItem() {
Text(day)
.padding(10)
.backgroundColor(Color.Green)
.borderRadius(5)
}
})
}
.layoutWeight(1)
.width('100%')
}
.padding(20)
.width('100%')
.height('100%')
}
}
2. 关键功能说明
-
数据持久化:
- 使用
Preferences
存储打卡记录 - 在
aboutToAppear
生命周期加载数据 - 打卡时更新并保存数据
- 使用
-
连续天数计算:
- 倒序遍历打卡记录
- 通过
isConsecutiveDate
方法判断日期连续性
-
UI组件:
- 使用
Button
触发打卡 List
展示历史打卡日期- 动态显示连续打卡天数
- 使用
3. 扩展功能建议
- 日历视图展示:
// 在build方法中添加日历视图
Grid() {
ForEach(this.getLast7Days(), (day: string) => {
GridItem() {
Column() {
Text(day.split('-')[2]) // 显示日期
.fontSize(16)
Circle()
.width(20)
.height(20)
.fill(this.clockInDays.includes(day) ? Color.Green : Color.Gray)
}
}
})
}
.columnsTemplate('1fr 1fr 1fr 1fr 1fr 1fr 1fr')
.rowsGap(10)
.columnsGap(5)
.margin(10)
- 打卡动画:
// 添加动画效果
@State isAnimating: boolean = false
Button('点击打卡')
.scale(this.isAnimating ? 1.2 : 1)
.animation({ duration: 500, curve: Curve.EaseInOut })
.onClick(() => {
this.isAnimating = true;
this.onClockIn();
setTimeout(() => this.isAnimating = false, 500);
})
4. 注意事项
-
时区处理:
- 使用
new Date().toLocaleDateString('zh-CN')
获取本地日期 - 确保设备时区设置正确
- 使用
-
数据安全:
- 对
clockInDays
数组操作时使用不可变数据(spread operator) - 添加异常捕获处理存储操作
- 对
-
性能优化:
- 当打卡记录较多时,使用虚拟列表(LazyForEach)
- 对日期计算使用缓存机制
如果需要更复杂的日历组件,可以参考鸿蒙的 Calendar
组件 进行扩展。

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。
更多推荐
所有评论(0)