open harmony 项目实战:学习打卡功能如何设计更有激励感
open harmony 项目实战:学习打卡功能如何设计更有激励感
学习类 App 想让用户持续打开,不能只靠内容堆叠,还要给用户一点“我正在进步”的反馈。
“语文视界”的学习中心里做了每日打卡、本周进度、连续学习天数和今日任务展示。这个功能不复杂,但很适合作为教育类 App 的留存入口。☀️
一、学习中心展示什么
学习中心第一屏包含:
- 连续学习天数
- 今日学习状态
- 本周打卡进度
- 今日背诵任务
- 诗词背诵、默写、配对、朝代排序模块
这些内容组合起来,会让用户一打开页面就知道:今天有没有学、已经坚持多久、接下来可以做什么。
二、核心状态
@State currentStreak: number = 0;
@State todayCompleted: boolean = false;
@State private checkInDatesStr: string = '';
currentStreak 是连续天数,todayCompleted 表示今天是否完成,checkInDatesStr 记录已打卡日期。
项目里用 | 分隔日期:
2026-6-28|2026-6-29|2026-6-30
这种做法简单,适合轻量本地状态。
三、读取本地数据
进入页面时会加载持久化数据:
private loadPersistedData(): void {
this.migrateLegacyCheckInIfNeeded();
const raw = AppStorage.get<string>('learn_checkin_dates');
this.checkInDatesStr = raw !== undefined && raw.length > 0 ? raw : '';
const today = this.getTodayDate();
const lastCheckIn = AppStorage.get<string>('learn_last_checkin_date') || '';
this.todayCompleted = this.isDateChecked(today);
}
这里还调用了 migrateLegacyCheckInIfNeeded,说明项目考虑到了旧版本数据兼容。
四、旧数据迁移
如果旧版本只保存了 learn_checkin_today 和 learn_streak_date,新版本会迁移到日期列表:
private migrateLegacyCheckInIfNeeded(): void {
const hasNew = AppStorage.get<string>('learn_checkin_dates');
if (hasNew !== undefined && hasNew.length > 0) {
return;
}
const oldDate = AppStorage.get<string>('learn_streak_date');
const oldDone = AppStorage.get<boolean>('learn_checkin_today');
if (oldDate !== undefined && oldDate.length > 0 && oldDone === true) {
AppStorage.setOrCreate('learn_checkin_dates', oldDate);
AppStorage.setOrCreate('learn_last_checkin_date', oldDate);
}
}
这个细节很适合写到文章里,因为它比普通 Demo 更像真实项目。
五、防止重复打卡
用户点击打卡时,先判断今天是否已经打过:
if (this.isDateChecked(today)) {
promptAction.showToast({ message: '今日已打卡 ♡', duration: 1500 });
return;
}
已经打卡就提示,不重复增加天数。
六、连续天数计算
项目会比较上次打卡日期和昨天:
const yesterday = this.getYesterdayDate();
let streak = AppStorage.get<number>('learn_streak');
if (streak === undefined) {
streak = 0;
}
if (last === yesterday) {
streak = streak + 1;
} else if (last !== today) {
streak = 1;
}
如果昨天也打卡,就连续天数 +1;如果中断了,就从 1 开始。
七、保存打卡状态
private savePersistedData(): void {
AppStorage.setOrCreate('learn_streak', this.currentStreak);
AppStorage.setOrCreate('learn_streak_date', this.getTodayDate());
AppStorage.setOrCreate('learn_checkin_today', this.todayCompleted);
AppStorage.setOrCreate('learn_checkin_dates', this.checkInDatesStr);
AppStorage.setOrCreate('learn_last_checkin_date', this.getTodayDate());
}
保存字段比较多,是为了兼容当前页面展示和旧版本逻辑。
八、本周进度展示
页面通过 7 个格子展示周一到周日:
ForEach([0, 1, 2, 3, 4, 5, 6], (index: number) => {
Column() {
Text(this.getWeekDayName(index));
Column() {
if (this.isWeekSlotChecked(index)) {
Text('✓');
} else {
Text('○');
}
}
}
});
这类视觉反馈能让用户快速感知自己的学习节奏。
九、激励感来自哪里
这个功能的激励感主要来自四点:
- 数字反馈:连续多少天。
- 状态反馈:今日已完成/进行中。
- 视觉反馈:本周格子点亮。
- 即时反馈:Toast 提示打卡成功。
学习类产品不一定要做复杂游戏化,简单而稳定的反馈就很有效。
总结
每日打卡功能本身不难,真正值得注意的是状态设计:日期怎么存、连续天数怎么算、重复打卡怎么拦、旧数据怎么迁移、本周进度怎么展示。
这个项目用 AppStorage 就实现了一套完整的本地打卡方案,轻量但够用,很适合 OpenHarmony 教育类 App 借鉴。🌟

更多推荐

所有评论(0)