HarmonyOS 应用开发《掌上英语》第50篇:题本与收藏——用户数据的本地管理
错题本与收藏——用户数据的本地管理一、功能概述错题本和收藏是学习应用中两个重要的辅助功能。错题本自动收集用户答错的题目供后续复习收藏则让用户可以手动标记重点题目建立自己的学习素材库。两者的数据都存储在本地 Preferences 中使用单独的 KeyexportclassPreferConstant{staticreadonlyERROR_RECORDS:stringERROR_RECORDS;// 错题记录staticreadonlyEXAM_PREFER_COLLECT:stringEXAM_PREFER_COLLECT;// 收藏记录}二、错题自动记录2.1 记录时机错题记录在 AnswerQuestionsPage 中自动触发。当用户选择答案后系统判断storageWrongClick(){// 排除从错题本或收藏进入的情况if(this.sourceRouterModel?.sourceType我的错题){return;}if(this.sourceRouterModel?.sourceType我的收藏){return;}if(this.sourceRouterModel?.sourceType错题练习){return;}if(this.currentModel){// 只有当选择答案不等于正确答案时才记录为错题if(this.currentModel.selectQues.toString()!this.currentModel.rightQues.toString()){letcurrentItemthis.transTopicItemType();if(currentItem){letarr:TopicItemType[]PreferenceUtil.getInstance().get(PreferConstant.ERROR_RECORDS,[])asTopicItemType[];if(arr.length0){arr.push(currentItem);}else{letisExitfalse;arr.forEach((itemType:TopicItemType,idx:number){if(itemType.keyIDcurrentItem?.keyID){arr[idx]currentItem;// 更新已存在的错题isExittrue;}});if(!isExit){arr.push(currentItem);// 新增错题}}PreferenceUtil.getInstance().put(PreferConstant.ERROR_RECORDS,arr);}}}}关键设计自动记录答错即记录无需用户手动操作去重更新同一题多次答错只保留最新一条记录排除干扰从错题本进入练习时不再重复记录完整数据保存TopicItemType完整对象包含题目、选项、解析等2.2 收藏记录收藏需要用户手动触发storageCollectClick(){if(this.currentModel){letcollectItemthis.transTopicItemType();if(collectItem){letarr:TopicItemType[]PreferenceUtil.getInstance().get(PreferConstant.EXAM_PREFER_COLLECT,[])asTopicItemType[];if(arr.length0){arr.push(collectItem);}else{letisExitfalse;arr.forEach((itemType:TopicItemType,idx:number){if(itemType.keyIDthis.currentModel?.keyID){arr.splice(idx,1);// 再次点击取消收藏isExittrue;}});if(!isExit){arr.push(collectItem);}}PreferenceUtil.getInstance().put(PreferConstant.EXAM_PREFER_COLLECT,arr);}}}收藏是开关式操作点击收藏、再点击取消收藏。三、MyWrongPage——错题展示3.1 页面结构build(){Column(){this.topBuilder();// 顶部导航 全选/删除按钮if(this.wrongQues.length0){Text(暂无易错词汇加油学习吧);// 空状态}else{this.wrongListBuilder();// 错题列表this.deleteBuilder();// 批量删除按钮}}}3.2 数据加载asyncinitData(){try{letarr:TopicItemType[]PreferenceUtil.getInstance().get(PreferConstant.ERROR_RECORDS,[])asTopicItemType[];arr.sort((a,b)b.jlStamp-a.jlStamp);// 按时间戳倒序this.wrongArrarr;if(arrarr.length0){arr.forEach((element:TopicItemType){letmodel:WrongModelnewWrongModel();model.isDeletefalse;model.keyIDelement.keyID;model.titleelement.title;this.wrongQues.push(model);});}}catch(e){this.wrongArr[];this.wrongQues[];}}数据加载要点从PreferConstant.ERROR_RECORDS读取按时间戳jlStamp倒序排列最新错误在最前面转换为WrongModel列表用于 UI 显示3.3 空状态处理if(this.wrongQues.length0){Text(暂无易错词汇加油学习吧).fontSize($r(sys.float.Body_S)).fontColor($r(sys.color.icon_secondary)).height(100%);}当错题列表为空时居中显示友好的提示文字。这是用户体验的基本要求——不因数据为空而显示空白页面。3.4 错题列表BuilderwrongListBuilder(){List(){ForEach(this.wrongQues,(item:WrongModel,idx:number){ListItem(){MyWrongItem({isSelectDelete:this.isSelectDelete,item:item,changeCollectionItem:(){/* 切换选中状态 */},idx:idx})}.swipeAction({end:{builder:(){this.itemEndComponent(idx);}}}).onClick((){// 点击进入答题页面letrouterModel:QuestionsRouterModelnewQuestionsRouterModel();routerModel.datalist[this.wrongArr[idx]];routerModel.sourceType易错词汇;RouterModule.push({url:RouterMap.ANSWER_QUESTIONS_PAGE,param:routerModel});});});}}列表支持两种操作左滑删除通过swipeAction实现单条删除点击进入练习点击错题跳转到答题页面sourceType标记为易错词汇3.5 批量删除BuilderdeleteBuilder(){Row(){Image($r(app.media.icon_delete));Text(删除);}.opacity(this.selectCount0?1:0.4).visibility(this.isSelectDelete?Visibility.Visible:Visibility.None).onClick((){this.deleteSelectData();});}批量删除模式点击顶部的删除图标进入选择模式勾选要删除的错题点击删除按钮批量清除。deleteSelectData(){letarr:string[][];this.wrongQues.forEach((model:WrongModel){if(model.isDelete){arr.push(model.keyID);}});this.wrongQuesthis.wrongQues.filter(it!it.isDelete);this.wrongArrthis.wrongArr.filter(it!arr.includes(it.keyID));PreferenceUtil.getInstance().put(PreferConstant.ERROR_RECORDS,this.wrongArr);}删除时同时更新内存中的wrongQues和wrongArr以及持久化存储。四、收藏的展示与使用收藏的数据结构和使用模式与错题本完全一致只是存储 Key 不同EXAM_PREFER_COLLECT。在 AnswerQuestionsPage 中从收藏列表进入答题时if(this.sourceRouterModel?.sourceType我的收藏){RouterModule.pop();// 收藏模式点击返回直接退出}收藏列表页MyCollectionPage的 UI 结构和 MyWrongPage 基本一致同样支持删除和点击进入答题。五、数据管理要点5.1 存储格式错题和收藏都使用TopicItemType[]数组存储。每个元素包含interfaceTopicItemType{keyID:string// 唯一标识title:string// 题目内容type:string// 题型rightQues:string[]// 正确答案selectQues:string[]// 用户选择ques:AnswerItemType[]// 选项列表parse:string// 解析jlStamp:number// 记录时间戳// ...}5.2 数据隔离错题和收藏使用不同的 Key互不干扰。同一个题目可以同时出现在错题本和收藏中。5.3 性能考虑Preferences 适合存储较小体量的数据。对于错题和收藏这种单用户最多几百条的场景完全足够。如果将来数据量增长到数千条可以考虑迁移到关系型数据库如kit.ArkData中的relationalStore。六、总结错题本和收藏功能展示了 Preferences 在用户私有数据存储中的典型应用。自动记录 手动收藏的组合覆盖了系统推荐和用户自选两种学习素材收集模式。结合空状态处理、批量操作、滑动删除等交互细节为用户提供了完整的数据管理体验。