【OpenHarmony/HarmonyOs 】实验室首页细节拆解:分类侧栏、搜索筛选与推荐探索交互
【OpenHarmony/HarmonyOs 】实验室首页细节拆解分类侧栏、搜索筛选与推荐探索交互本文基于我的 OpenHarmony/HarmonyOS 项目「物理视界 PhysicsVision」整理。实验室首页是整个应用的核心入口它承载了 28 个物理模型的分类展示、年级筛选、关键词搜索、最近浏览、推荐探索和随机探索。这一篇单独拆实验室首页的交互细节重点对应“全新视觉与交互体验”和“端侧智能推荐”的主题。一、实验室首页承担什么角色一个物理学习 App 不能只是把所有模型堆成一个列表。如果模型数量多用户很快会遇到几个问题不知道从哪里开始学找不到某个具体模型不清楚哪些模型适合自己年级学过的内容和没学过的内容混在一起每次打开都要重新寻找上次内容。「物理视界」的实验室首页就是为了解决这些问题。它不是简单列表而是一个学习入口左侧分类侧栏按学科方向筛选年级筛选按初中、高一、高二、高三定位搜索栏按模型名、描述、分类、难度搜索推荐探索优先推荐未学习的基础模型最近浏览帮助用户回到上次学习随机探索降低选择成本。这些细节组合起来就形成了一个很完整的学习流。二、模型数据的结构化组织实验室页中模型不是孤立存在的而是用多个数组维护元数据privatenames:string[] [声音的传播,光的反射,串并联电路,匀变速直线运动,自由落体,力的合成与分解]privatedescs:string[] [探索声波在不同介质中的传播,观察光线的反射规律,理解串联与并联电路特性,研究匀变速运动的规律]privategradeTags:string[] [初中,初中,初中,高一,高一]privatecategoryTags:string[] [波动,光学,电磁学,力学,力学]每个模型都有名称、描述、年级、分类、难度和路由。这让首页可以做筛选、搜索、推荐、统计和跳转。如果后续接入元服务或近场快传这些结构化数据也能直接复用。三、左侧分类侧栏让知识结构更清楚项目中分类包括privatecategories:string[] [全部,力学,电磁学,光学,热学,波动]侧栏每个分类都有图标和选中态ForEach(this.categories, (c:string,index:number) {Column({space: 4 }){Image(this.catIconRes[index]).width(20) .height(20) .fillColor(this.selectedCategoryindex?this.getCatAccent(index):$r(app.color.icon_gray))Text(c).fontSize(10).fontWeight(this.selectedCategoryindex? FontWeight.Bold : FontWeight.Normal).fontColor(this.selectedCategoryindex?this.getCatAccent(index):$r(app.color.text_sub)) } .backgroundColor(this.selectedCategoryindex? $r(app.color.bg_card): Color.Transparent) .borderRadius(12).onClick(() { animateTo({duration: 200,curve: Curve.EaseOut }, () { this.selectedCategory index }) this.updateDisplayList()}) })这段代码体现了三个细节图标和文字都跟随选中态变化点击分类后有轻动画状态变化后立即刷新模型列表。这种侧栏很适合知识型应用因为它能把内容结构放在用户眼前。四、年级筛选贴合学习阶段物理内容和年级强相关所以项目提供了年级筛选privategrades:string[] [全部,初中,高一,高二,高三]筛选按钮使用轻量文本块ForEach(this.grades, (g:string,index:number) {Text(g).fontSize(11).fontWeight(this.selectedGradeindex? FontWeight.Bold : FontWeight.Normal).fontColor(this.selectedGradeindex? #1A73E8 : $r(app.color.text_weak)) .backgroundColor(this.selectedGradeindex? $r(app.color.result_bg): Color.Transparent) .borderRadius(10).onClick(() { animateTo({duration: 200,curve: Curve.EaseOut }, () { this.selectedGrade index }) this.updateDisplayList()}) })年级筛选可以避免学生一上来就看到太难的内容。这也符合教育应用的基本原则先让用户找到适合自己的学习层级。五、搜索栏多字段匹配搜索不是只匹配名称而是匹配多个字段let searchMatch:boolean keyword.length 0||this.names[i].includes(keyword) ||this.descs[i].includes(keyword) ||this.categoryTags[i].includes(keyword) ||this.gradeTags[i].includes(keyword) ||this.difficulties[i].includes(keyword)这意味着用户输入“光学”可以找到光学模型“高三”可以找到高三模型“挑战”可以找到高难度内容“电场”可以找到电场线、电场偏转。对学习应用来说搜索应该理解用户的意图而不是只做标题匹配。六、筛选主逻辑分类、年级、搜索同时生效完整筛选逻辑如下updateDisplayList(): void {this.listAnim falselet result: number[] [] let keyword: string this.searchText.trim()for(let i 0; i this.names.length; i) { let categoryMatch: boolean this.selectedCategory 0||this.categoryTags[i] this.categories[this.selectedCategory] let gradeMatch: boolean this.selectedGrade 0||this.gradeTags[i] this.grades[this.selectedGrade] let searchMatch: boolean keyword.length 0||this.names[i].includes(keyword) ||this.descs[i].includes(keyword)if(categoryMatch gradeMatch searchMatch) { result.push(i) } }this.displayList result }这里使用的是“且”关系分类要匹配年级要匹配搜索要匹配。这样筛选结果更精准。七、推荐探索项目里的端侧智能雏形推荐逻辑优先找未探索的基础模型getRecommended(): number[] { let result: number[] []for(let i 0; i this.names.length; i) {if(!this.isVisited(i) this.difficulties[i] 基础) { result.push(i)if(result.length 4)break} }if(result.length 4) {for(let i 0; i this.names.length; i) {if(!this.isVisited(i) this.difficulties[i] 进阶) { result.push(i)if(result.length 4)break} } }returnresult }虽然这不是大模型 AI但它是很实用的端侧智能不联网不上传用户数据根据本地学习状态推荐规则可解释。对于教育应用来说这种“本地可解释推荐”比黑盒推荐更可靠。八、最近浏览学习不断线最近浏览列表取最近 6 个模型updateRecentList():void{if(this.visitedModels.length0) {this.recentList []return}letparts:string[] this.visitedModels.split(,)letresult:number[] []letstart:number parts.length6? parts.length-6:0for(leti parts.length-1; i start; i--) {letval:numberparseInt(parts[i])if(val 0 val this.names.length) { result.push(val) } }this.recentList result }这个功能非常适合全场景智慧学习。用户在手机上学过一个模型后续如果做跨设备同步或备份恢复就能在平板继续学习。九、随机探索降低选择压力项目还提供随机探索navigateToRandom():void{letunvisited:number[] []for(leti 0; i this.names.length; i) {if(!this.isVisited(i)) unvisited.push(i) }lettarget:number0if(unvisited.length0) { target unvisited[Math.floor(Math.random() * unvisited.length)] }else{ target Math.floor(Math.random() *this.names.length) }this.recordVisit(target) router.pushUrl({url:this.routes[target] }).catch(() {}) }它优先随机未探索模型而不是完全随机。这也是一个小小的学习引导用户想不出学什么时系统帮他迈出下一步。十、总结实验室首页的价值不只是展示模型而是组织学习路径。分类侧栏、年级筛选、关键词搜索、推荐探索、最近浏览、随机探索这些功能共同构成了一个轻量但完整的学习入口。这篇文章对应的主题是全新视觉与交互体验 端侧智能推荐 全场景学习续接。它没有脱离项目因为所有细节都来自当前代码它也没有空谈 AI而是从本地学习状态出发说明如何把一个模型列表做成真正可用的学习首页。