HarmonyOS 应用开发《掌上英语》第48篇:学习进度追踪——从数据记录到可视化展示
学习进度追踪——从数据记录到可视化展示一、进度追踪的整体架构学习进度追踪是英语学习 App 的核心功能之一。用户需要知道今天学了多少、“总共学了多少”、“目标完成得怎么样”。本项目通过 LearningPlanManager 管理目标数据通过 CourseHomePage 和首页的 Progress 组件进行可视化展示。数据流如下用户答题 → recordWordStudy(count) ↓ LearningPlanManager ├── todayWordCount → 今日已学 ├── totalWordCount → 累计已学 ├── continuousDays → 连续天数 └── getTodayProgress() → 百分比 ↓ CourseHomePage / MainPage └── Progress 组件 → 可视化展示二、学习计划的定义2.1 LearningPlan 模型exportinterfaceLearningPlan{dailyWordGoal:number// 每日单词目标dailyListeningGoal:number// 每日听力目标分钟dailyReadingGoal:number// 每日阅读目标分钟continuousDays:number// 连续学习天数lastStudyDate:number// 最后学习日期时间戳todayWordCount:number// 今日已学单词todayListeningDuration:number// 今日已听时长todayReadingDuration:number// 今日已读时长totalWordCount:number// 总学习单词数totalStudyDuration:number// 总学习时长badges:string[]// 成就徽章// ... 提醒相关字段}默认计划DEFAULT_LEARNING_PLAN为每日 20 个单词、15 分钟听力、10 分钟阅读。2.2 数据记录入口在 AnswerQuestionsPage 完成答题后通过recordStudyData方法记录学习数据recordStudyData(){try{lettopicItemTypeListthis.toTopicItemTypeList(this.ques);// 1. 记录统计StatisticsManager.getInstance().calculateStatistics(topicItemTypeList,this.practiceDuration);// 2. 更新学习计划letplanManagerLearningPlanManager.getInstance();letansweredCountthis.ques.filter(itemitem.isAnswer).length;planManager.recordWordStudy(answeredCount);}catch(e){Logger.error(AnswerQuestionsPage,记录学习数据失败:${JSON.stringify(e)});}}recordWordStudy方法执行三个操作累加todayWordCount和totalWordCount调用checkAndUpdateContinuousDays更新连续天数调用checkAndUnlockBadges检查是否满足徽章解锁条件三、今日进度计算3.1 百分比计算publicgetTodayProgress():TodayProgress{try{letplanthis.getLearningPlan();letresult:TodayProgress{wordProgress:plan.dailyWordGoal0?Math.min(100,Math.floor(plan.todayWordCount/plan.dailyWordGoal*100)):0,listeningProgress:plan.dailyListeningGoal0?Math.min(100,Math.floor(plan.todayListeningDuration/plan.dailyListeningGoal*100)):0,readingProgress:plan.dailyReadingGoal0?Math.min(100,Math.floor(plan.todayReadingDuration/plan.dailyReadingGoal*100)):0};returnresult;}catch(e){Logger.error(LearningPlanManager,获取今日进度失败:${JSON.stringify(e)});return{wordProgress:0,listeningProgress:0,readingProgress:0};}}关键点Math.min(100, ...)防止进度超过 100%目标为 0 时返回 0%避免除零错误每个维度独立计算单词、听力、阅读3.2 首页进度卡展示在 CourseHomePage 中进度通过 Progress 组件展示Row(){Column(){Text(${this.learnedCount}/${this.totalCount}).fontSize(22).fontWeight(FontWeight.Bold).fontColor(#165DFF);Text(已学 / 总数).fontSize(11).fontColor($r(sys.color.font_secondary));}.layoutWeight(1);Column(){Text(今日需学 30 词).fontSize(13);Text(已完成${this.learnedCount}词).fontSize(11);}}Progress({value:this.getTodayProgress(),total:30,type:ProgressType.Linear}).width(100%).height(6).color(#165DFF).backgroundColor(#E8EEF8);这里使用了ProgressType.Linear线性进度条以30为每日目标总数value是当前已学数量。四、总进度统计4.1 学习统计摘要publicgetStudySummary():StudySummary{try{letplanthis.getLearningPlan();letresult:StudySummary{totalDays:plan.continuousDays,totalWords:plan.totalWordCount,totalDuration:plan.totalStudyDuration,badgeCount:plan.badges.length};returnresult;}catch(e){Logger.error(LearningPlanManager,获取学习统计摘要失败:${JSON.stringify(e)});return{totalDays:0,totalWords:0,totalDuration:0,badgeCount:0};}}这个摘要方法返回四个关键指标可以在学习报告页面统一呈现。4.2 学习报告中的 Dashboard 集成DashboardManager 也整合了进度数据publicrefreshData():void{letplanManagerLearningPlanManager.getInstance();letstatsManagerStatisticsManager.getInstance();letplanplanManager.getLearningPlan();letprogressplanManager.getTodayProgress();letsummarystatsManager.getHistoryStatistics();this.todayWordProgressprogress.wordProgress;this.todayListeningProgressprogress.listeningProgress;this.todayReadingProgressprogress.readingProgress;this.overallProgressMath.floor((this.todayWordProgressthis.todayListeningProgressthis.todayReadingProgress)/3);this.continuousDaysplan.continuousDays;this.weeklyDatathis.buildWeeklyData(plan);// ...}overallProgress是三个进度维度的平均值用于展示总体完成度。五、Progress 组件的两种形态5.1 线性进度条ProgressType.LinearProgress({value:13,total:30,type:ProgressType.Linear}).width(100).height(6).color(#165DFF).backgroundColor(#E8EEF8);适用场景展示单词学习进度、阅读进度。形态简洁适合嵌入卡片中。5.2 环形进度条ProgressType.RingProgress({value:65,total:100,type:ProgressType.Ring}).width(50).height(50).color(#165DFF).style({strokeWidth:4});适用场景首页今日学习卡中的总体进度。圆形视觉更醒目适合作为模块的视觉锚点。5.3 柱状图自定义实现DashboardManager 中的 WeeklyBarChart 不使用系统的 Progress 组件而是用 Row 组件模拟柱状图Column(){if(item.readingMin0){Row().width(20).height(this.barHeight(item.readingMin)).backgroundColor(#FF9800);}if(item.listeningMin0){Row().width(20).height(this.barHeight(item.listeningMin)).backgroundColor(#4CAF50);}if(item.wordCount0){Row().width(20).height(this.barHeight(item.wordCount)).backgroundColor(#2196F3);}}.height(120).justifyContent(FlexAlign.End);堆叠柱状条每种颜色代表一个维度的数据高度通过barHeight方法按比例计算。六、每日数据重置新的一天开始时需要重置今日学习数据publicresetDailyData():LearningPlan{try{letplanthis.getLearningPlan();plan.todayWordCount0;plan.todayListeningDuration0;plan.todayReadingDuration0;this.saveLearningPlan(plan);returnplan;}catch(e){Logger.error(LearningPlanManager,重置每日数据失败:${JSON.stringify(e)});returnthis.getLearningPlan();}}实际调用时机在checkAndUpdateContinuousDays中隐式完成——当检测到「最后学习日期不是今天」时新的记录会自然产生新的今日数据旧数据不再被引用。七、总结从 LearningPlanManager 的数据记录到 Progress 组件的可视化呈现学习进度追踪形成了一条完整的数据链路。三个维度的目标单词、听力、阅读、两种进度形态线性条、环形、以及柱状图等自定义图表共同构成了用户学习旅程的仪表盘让进步看得见。

相关新闻

多模态RAG技术:跨模态检索与生成实战解析

多模态RAG技术:跨模态检索与生成实战解析

1. 多模态RAG技术全景解析当我们在2023年观察到GPT-4V能够同时理解图像和文本时,一个关键问题随之浮现:如何让大语言模型突破纯文本的局限,真正实现多模态知识的融合与应用?这正是多模态RAG(Retrieval-Augmented Gener…

2026/10/14 4:13:21 阅读更多 →
智能体反思能力架构设计与工程实践

智能体反思能力架构设计与工程实践

1. 项目概述在AI领域,让智能体(Agent)具备反思能力是一个极具挑战性的前沿课题。不同于传统程序化的任务执行,具备反思能力的Agent能够像人类一样审视自己的行为、评估决策质量,并在后续行动中进行自我调整。这种能力对…

2026/10/15 0:48:25 阅读更多 →
像素即坐标:工业机器人视觉定位新方法

像素即坐标:工业机器人视觉定位新方法

1. 项目背景与核心价值去年在给工业机器人做视觉定位系统升级时,我发现传统坐标系转换方法存在一个致命缺陷:当摄像头与机械臂安装角度超过45度后,定位误差会呈指数级增长。这个问题困扰了我整整三个月,直到偶然看到女儿玩的《我的…

2026/10/15 0:42:41 阅读更多 →

最新新闻

从柯西-施瓦兹不等式到匹配滤波:工程直觉与实战避坑指南

从柯西-施瓦兹不等式到匹配滤波:工程直觉与实战避坑指南

简介:这份资料围绕雷达信号处理中的匹配滤波技术展开,从柯西施瓦兹不等式这一数学基础切入,帮助读者理解匹配滤波器的理论来源与工程实现。内容适合具备一定信号处理与线性代数基础的高校学生、科研人员及雷达工程从业者,用于解决…

2026/10/15 0:48:41 阅读更多 →
手写C++ OBJ文件解析器:从格式到百万顶点优化与避坑指南

手写C++ OBJ文件解析器:从格式到百万顶点优化与避坑指南

简介:面向需要处理Wavefront OBJ三维模型格式的开发者和图形学入门者,这份资源提供一套基于Visual Studio 2013的obj解析C源码。源码实现完整的读取流程,覆盖顶点、纹理坐标、法线及多边形面这几类核心指令的解析,通过文件流逐行读…

2026/10/15 0:48:41 阅读更多 →
superpowers:用SKILL.md让Claude Code变身高效率AI开发助手

superpowers:用SKILL.md让Claude Code变身高效率AI开发助手

1. 先搞清楚:superpowers 到底是什么如果你平时用 Claude Code 比较多,可能早就遇到了一个让我当初很头疼的问题:底层模型确实聪明,但你在对话里让它"做个深度调研""写一套完整的单测""把这次的改动整理…

2026/10/15 0:48:41 阅读更多 →
用repomap给Claude Code一张代码地图,工具调用从52次降到3次

用repomap给Claude Code一张代码地图,工具调用从52次降到3次

1. 52 次工具调用到底是怎么花掉的我一直觉得 Claude Code 这类 CLI 编程助手最让人上头的点是“它真的会自己去翻代码库”,但最让人血压升高的点也是“它真的会自己去翻代码库”。刚上手那会儿,我在一个两万行左右的项目里让它排查登录流程的 token 过期…

2026/10/15 0:48:41 阅读更多 →
C#调用MATLAB绘图实战:COM自动化、句柄管理与嵌入式集成

C#调用MATLAB绘图实战:COM自动化、句柄管理与嵌入式集成

简介:本资源面向C#开发者与MATLAB混合编程实践者,解决在Windows平台下利用MATLAB强大图形引擎(尤其三维可视化)弥补C#原生绘图能力不足的核心问题。适用于科学计算、工程仿真、教学演示等需高质量数学图形的中高级开发场景。压缩包…

2026/10/15 0:48:41 阅读更多 →
在河北开发直播 APP,怎么挑选靠谱的软件公司?

在河北开发直播 APP,怎么挑选靠谱的软件公司?

河北不少创业者、企业都想搭建自己的直播 APP,带货直播、付费课程、娱乐打赏、私域直播等需求越来越多。但直播属于音视频高并发项目,技术门槛远高于普通商城和管理系统。很多本地软件公司只会做简单小程序,并不具备流媒体开发经验&#xff0…

2026/10/15 0:47:40 阅读更多 →

日新闻

Docker Compose 容器化部署 ChirpStack LoRaWAN 网络服务器实战

Docker Compose 容器化部署 ChirpStack LoRaWAN 网络服务器实战

1. 为什么选择容器化方式部署 LoRa 网络服务LoRa 物联网项目落地时,网络服务器是整个链路的核心枢纽。它负责接收网关上报的数据包、完成去重与解密、再把有效载荷分发给上层应用。早期大家习惯把网络服务器直接装在物理机上,依赖一堆系统库和特定版本的…

2026/10/15 0:00:46 阅读更多 →
共享LLM服务下的跨模型自动扩缩容:Kubernetes实战与避坑指南

共享LLM服务下的跨模型自动扩缩容:Kubernetes实战与避坑指南

1. 共享推理服务里,扩缩容到底难在哪做过大模型推理服务部署的人,大概都经历过这样的场景:一个团队共用一套推理集群,A 业务跑的是 7B 的小模型,B 业务跑的是 72B 的大模型,C 业务白天流量高、晚上几乎归零…

2026/10/15 0:00:46 阅读更多 →
Systemd 启动阶段根文件系统只读之谜:fstab 与 remount-fs 服务深度解析

Systemd 启动阶段根文件系统只读之谜:fstab 与 remount-fs 服务深度解析

1. 引子:一次内核恐慌引发的追查先从一个真实场景说起。某次我给一台老旧的嵌入式设备折腾系统裁减,为了把启动时间压进两秒以内,我手贱地把一串自认为“没用”的 systemd 服务给 disable 了,其中就包括systemd-remount-fs.servic…

2026/10/15 0:00:46 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/14 3:30:28 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/14 16:30:29 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/14 3:29:58 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/15 0:14:36 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/14 22:45:47 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/14 7:53:34 阅读更多 →