【OpenHarmony/HarmonyOs 】每日学习目标系统:todayCount、连续学习与本地激励反馈
【OpenHarmony/HarmonyOs 】每日学习目标系统:todayCount、连续学习与本地激励反馈
项目类型:OpenHarmony / HarmonyOS ArkTS 数学学习应用
项目名称:数学视界
对应主题:全新视觉与交互体验、端侧 AI、全场景智慧学习
关键词:ArkTS、每日目标、学习进度、连续学习、成就激励、本地统计 🎯
一、为什么每日目标值得写?
学习类应用最难的不是做功能,而是让用户持续回来。数学视界里有计算器、公式库、单位换算、挑战答题、趣味百科、曲线画板,但如果没有一个持续激励机制,这些功能容易变成“用完即走”的工具。
每日学习目标就是把工具型应用变成学习型应用的关键。
项目中围绕每日目标做了几件事:
- 首页展示今日进度;
- 我的页面展示目标进度;
- 用户可以修改每日目标;
- 计算、换算、绘图等行为会增加
todayCount; - 达成目标后更新连续达标天数;
- 连续完成目标可以解锁成就。
这篇文章就聚焦这个本地激励系统。
二、StudyData:每日目标的数据基础
每日目标相关数据定义在 AppState.ets:
export interface StudyData {
totalStudyDays: number
currentStreak: number
totalDrawings: number
totalCalculations: number
totalFunctions: number
totalFormulasViewed: number
totalUnitsConverted: number
lastStudyDate: string
dailyGoal: number
todayCount: number
consecutiveGoalMetDays: number
funFactsViewed: number
}
这里最关键的是:
dailyGoal:每天目标数量;todayCount:今日已完成数量;currentStreak:连续学习天数;consecutiveGoalMetDays:连续达成目标天数;lastStudyDate:最后学习日期。
这些数据全部在端侧维护,不需要账号系统,也不需要云端学习画像。
三、哪些行为算一次学习?
项目中多个功能会增加学习计数。例如单位换算:
recordUnitConversion(): void {
this.studyData.totalUnitsConverted++
this.studyData.todayCount++
this.updateStudyStreak()
this.checkAchievement('11')
this.checkDailyGoalMet()
}
计算器也会记录:
recordCalculation(): void {
this.studyData.totalCalculations++
this.studyData.todayCount++
this.updateStudyStreak()
this.checkAchievement('2')
this.checkDailyGoalMet()
}
画板绘制也会记录:
recordDrawing(): void {
this.studyData.totalDrawings++
this.studyData.todayCount++
this.updateStudyStreak()
this.checkDailyGoalMet()
}
这说明每日目标不是只服务于答题,而是覆盖整个数学学习行为。
四、首页进度卡:打开 App 就知道还差多少
首页的进度卡直接读取 todayCount 和 dailyGoal:
Column()
.width(Math.min(
AppState.studyData.todayCount /
AppState.studyData.dailyGoal * 100,
100
) + '%')
.height('100%')
.backgroundColor('#FFFFFF')
.borderRadius(10)
这段代码把学习进度转成进度条宽度。
底部文案也会根据目标完成情况变化:
Text(
AppState.studyData.todayCount >= AppState.studyData.dailyGoal
? '🎉 太棒了!今日目标达成!'
: '💪 再完成 ' +
Math.max(AppState.studyData.dailyGoal - AppState.studyData.todayCount, 0) +
' 次即可达成今日目标!'
)
这就是一个典型的轻量激励设计:不用弹窗打扰用户,但用户能随时看到当前进度。
五、我的页面进度:更完整的目标反馈
在 MyPage.ets 中,今日学习数量通过日期判断:
getTodayStudyCount(): number {
const today: string = new Date().toISOString().split('T')[0]
if (AppState.studyData.lastStudyDate === today) {
return AppState.studyData.todayCount
}
return 0
}
进度百分比:
getGoalProgress(): number {
const goal: number = AppState.settings.dailyGoal
const today: number = this.getTodayStudyCount()
if (goal <= 0) return 0
return Math.min(Math.round((today / goal) * 100), 100)
}
然后用 Progress 组件展示:
Progress({
value: this.getGoalProgress(),
total: 100,
type: ProgressType.Linear
})
.color(this.getGoalProgress() >= 100 ? '#2ECC71' : '#FF9A8B')
.backgroundColor(this.getColor('#F0F0F0', '#333333'))
.height(8)
.borderRadius(4)
首页负责快速提醒,我的页面负责完整查看。两个入口互补。
六、连续学习:跨天逻辑如何处理?
连续学习依赖 updateStudyStreak():
private updateStudyStreak(): void {
const today: string = new Date().toISOString().split('T')[0]
if (this.studyData.lastStudyDate === '') {
this.studyData.lastStudyDate = today
this.studyData.totalStudyDays = 1
this.studyData.currentStreak = 1
this.goalMetCheckedToday = false
} else if (this.studyData.lastStudyDate !== today) {
const lastDate: Date = new Date(this.studyData.lastStudyDate)
const todayDate: Date = new Date(today)
const diffDays: number =
Math.floor((todayDate.getTime() - lastDate.getTime()) /
(1000 * 60 * 60 * 24))
if (diffDays === 1) {
this.studyData.currentStreak++
} else if (diffDays > 1) {
this.studyData.currentStreak = 1
this.studyData.consecutiveGoalMetDays = 0
}
this.studyData.totalStudyDays++
this.studyData.lastStudyDate = today
this.studyData.todayCount = 0
this.goalMetCheckedToday = false
}
}
这个逻辑处理了三种情况:
- 第一次学习:初始化日期和连续天数;
- 第二天继续学习:连续天数加一;
- 中断多天后回来:连续天数重置。
七、目标达成:一天只检查一次
为了避免同一天重复触发目标成就,项目使用了 goalMetCheckedToday:
private goalMetCheckedToday: boolean = false
checkDailyGoalMet(): void {
if (!this.goalMetCheckedToday &&
this.studyData.todayCount >= this.studyData.dailyGoal) {
this.goalMetCheckedToday = true
this.studyData.consecutiveGoalMetDays++
this.checkGoalAchievement()
}
}
这个细节很重要。假设每日目标是 5 次,用户完成第 6 次、第 7 次时,不应该反复增加连续达标天数。
八、目标成就:连续 7 天完成目标
目标成就逻辑如下:
checkGoalAchievement(): void {
for (let i: number = 0; i < this.achievements.length; i++) {
if (this.achievements[i].id === '13' &&
!this.achievements[i].isUnlocked) {
this.achievements[i].progress =
this.studyData.consecutiveGoalMetDays
if (this.studyData.consecutiveGoalMetDays >= 7) {
this.achievements[i].progress = 7
this.achievements[i].isUnlocked = true
this.recentUnlock = this.achievements[i]
this.showUnlockToast = true
}
break
}
}
}
这让每日目标从“今天做几次”升级成“连续坚持”的长期激励。
九、隐私友好:不需要账号也能激励
很多学习 App 会把每日打卡、排名、学习报告上传到服务器。但数学视界当前的目标系统完全可以本地完成:
- 本地记录学习次数;
- 本地计算连续天数;
- 本地判断目标达成;
- 本地解锁成就。
这对学习工具来说非常友好。用户不需要登录,也能获得持续反馈。
十、总结
每日目标系统对应“全新视觉与交互体验”和“端侧 AI”主题,它把分散的工具功能串成了学习路径。
核心实现包括:
- 🎯 用
dailyGoal和todayCount表达每日目标; - 📈 首页用进度条和鼓励文案做即时反馈;
- 👤 我的页面用
Progress展示完整进度; - 📅 用
lastStudyDate和currentStreak计算连续学习; - 🏆 用
consecutiveGoalMetDays解锁目标成就; - 🔐 所有统计都在端侧完成,不依赖账号和云端。
对数学学习 App 来说,每日目标不是一个小组件,而是让用户持续学习的核心机制。✨

更多推荐



所有评论(0)