尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

HarmonyOS APP<玩转React>开源教程十六:课程列表页面

HarmonyOS APP<玩转React>开源教程十六:课程列表页面 第16次课程列表页面课程列表是用户浏览和选择学习内容的主要入口。本次课程将实现课程 Tab 的完整功能包括按难度分组展示、模块列表项设计等。列表效果学习目标掌握列表分组展示技巧学会设计模块列表项实现课程数量与时长显示优化列表滚动性能完成课程列表页面开发16.1 按难度分组展示分组设计将课程按难度等级分为 5 组 入门 (beginner) ├── React 简介 └── 环境搭建 基础 (basic) ├── 组件基础 ├── 事件与渲染 └── ... 进阶 (intermediate) ├── Hooks 基础三剑客 └── ... 高级 (advanced) ├── React 渲染原理 └── ... 生态 (ecosystem) ├── Next.js 框架 └── ...实现代码BuilderCourseContent(){Scroll(){Column(){// 标题Text(全部课程).fontSize(24).fontWeight(FontWeight.Bold).fontColor(this.isDarkMode?#ffffff:#1a1a2e).padding({left:16,top:16,bottom:16}).width(100%)// 按难度分组显示ForEach([beginner,basic,intermediate,advanced,ecosystem],(difficulty:string){this.DifficultySection(difficulty)})}.padding({bottom:20})}.width(100%).height(100%).scrollBar(BarState.Off)}16.2 难度分组区域分组标题privategetDifficultyTitle(difficulty:string):string{consttitles:Recordstring,string{beginner: 入门,basic: 基础,intermediate: 进阶,advanced: 高级,ecosystem: 生态};returntitles[difficulty]??difficulty;}分组区域实现BuilderDifficultySection(difficulty:string){Column(){// 难度标题Text(this.getDifficultyTitle(difficulty)).fontSize(16).fontWeight(FontWeight.Medium).fontColor(this.isDarkMode?#d1d5db:#495057).padding({left:16,top:16,bottom:8}).width(100%)// 该难度下的模块列表ForEach(this.modules.filter(mm.difficultydifficulty),(module:LearningModule){this.ModuleListItem(module)})}}16.3 模块列表项设计列表项布局┌─────────────────────────────────────────┐ │ │ 模块标题 │ › │ │ │ 3 课时 · 30分钟 │ │ └─────────────────────────────────────────┘实现代码BuilderModuleListItem(module:LearningModule){Row(){// 图标Text(module.icon).fontSize(28)// 信息区域Column(){Text(module.title).fontSize(16).fontWeight(FontWeight.Medium).fontColor(this.isDarkMode?#ffffff:#1a1a2e)Text(${module.lessonCount}课时 ·${module.estimatedTime}).fontSize(13).fontColor(this.isDarkMode?#d1d5db:#495057).margin({top:4})}.alignItems(HorizontalAlign.Start).margin({left:12}).layoutWeight(1)// 箭头Text(›).fontSize(20).fontColor(this.isDarkMode?#9ca3af:#6c757d)}.width(100%).padding(16).margin({left:16,right:16,bottom:8}).backgroundColor(this.isDarkMode?#282c34:#ffffff).borderRadius(12).onClick((){router.pushUrl({url:pages/ModuleDetail,params:{moduleId:module.id}});})}16.4 添加进度指示显示学习进度BuilderModuleListItem(module:LearningModule){Row(){Text(module.icon).fontSize(28)Column(){Row(){Text(module.title).fontSize(16).fontWeight(FontWeight.Medium).fontColor(this.isDarkMode?#ffffff:#1a1a2e)// 完成标记if(ProgressService.isModuleCompleted(module.id,this.progress)){Text(✓).fontSize(14).fontColor(#51cf66).margin({left:8})}}Text(${module.lessonCount}课时 ·${module.estimatedTime}).fontSize(13).fontColor(this.isDarkMode?#d1d5db:#495057).margin({top:4})// 进度条if(this.getModuleProgress(module)0!ProgressService.isModuleCompleted(module.id,this.progress)){Row(){Progress({value:this.getModuleProgress(module),total:100,type:ProgressType.Linear}).width(60%).height(3).color(this.isDarkMode?#61DAFB:#0077b6).backgroundColor(this.isDarkMode?#3d3d5c:#e9ecef)Text(${this.getModuleProgress(module)}%).fontSize(11).fontColor(this.isDarkMode?#61DAFB:#0077b6).margin({left:8})}.margin({top:8})}}.alignItems(HorizontalAlign.Start).margin({left:12}).layoutWeight(1)Text(›).fontSize(20).fontColor(this.isDarkMode?#9ca3af:#6c757d)}.width(100%).padding(16).margin({left:16,right:16,bottom:8}).backgroundColor(this.isDarkMode?#282c34:#ffffff).borderRadius(12).onClick((){router.pushUrl({url:pages/ModuleDetail,params:{moduleId:module.id}});})}// 获取模块进度privategetModuleProgress(module:LearningModule):number{returnProgressService.getCompletionPercentage(module,this.progress);}16.5 列表滚动优化LazyForEach 懒加载对于大量数据使用 LazyForEach 优化性能// 定义数据源classModuleDataSourceimplementsIDataSource{privatemodules:LearningModule[][];constructor(modules:LearningModule[]){this.modulesmodules;}totalCount():number{returnthis.modules.length;}getData(index:number):LearningModule{returnthis.modules[index];}registerDataChangeListener(listener:DataChangeListener):void{}unregisterDataChangeListener(listener:DataChangeListener):void{}}// 使用 LazyForEachLazyForEach(this.moduleDataSource,(module:LearningModule){this.ModuleListItem(module)},(module:LearningModule)module.id)列表项复用使用Reusable装饰器标记可复用组件ReusableComponentstruct ModuleListItemComponent{Propmodule:LearningModule{}asLearningModule;Propprogress:number0;PropisCompleted:booleanfalse;StorageLink(isDarkMode)isDarkMode:booleanfalse;onTap?:()void;build(){// 列表项内容...}}16.6 完整课程列表代码BuilderCourseContent(){Scroll(){Column(){// 页面标题Row(){Text(全部课程).fontSize(24).fontWeight(FontWeight.Bold).fontColor(this.isDarkMode?#ffffff:#1a1a2e)Blank()// 统计信息Text(${this.modules.length}个模块).fontSize(14).fontColor(this.isDarkMode?#61DAFB:#0077b6)}.width(100%).padding({left:16,right:16,top:16,bottom:16})// 按难度分组显示ForEach([beginner,basic,intermediate,advanced,ecosystem],(difficulty:string){// 只显示有模块的难度分组if(this.modules.some(mm.difficultydifficulty)){this.DifficultySection(difficulty)}})}.padding({bottom:20})}.width(100%).height(100%).scrollBar(BarState.Off)}BuilderDifficultySection(difficulty:string){Column(){// 分组标题Row(){Text(this.getDifficultyTitle(difficulty)).fontSize(16).fontWeight(FontWeight.Medium).fontColor(this.isDarkMode?#d1d5db:#495057)Blank()// 该难度模块数量Text(${this.modules.filter(mm.difficultydifficulty).length}个).fontSize(12).fontColor(this.isDarkMode?#9ca3af:#6c757d)}.width(100%).padding({left:16,right:16,top:16,bottom:8})// 模块列表ForEach(this.modules.filter(mm.difficultydifficulty),(module:LearningModule){this.ModuleListItem(module)})}}BuilderModuleListItem(module:LearningModule){Row(){Text(module.icon).fontSize(28)Column(){Row(){Text(module.title).fontSize(16).fontWeight(FontWeight.Medium).fontColor(this.isDarkMode?#ffffff:#1a1a2e).maxLines(1).textOverflow({overflow:TextOverflow.Ellipsis})if(ProgressService.isModuleCompleted(module.id,this.progress)){Text(✓).fontSize(14).fontColor(#51cf66).margin({left:8})}}.width(100%)Text(${module.lessonCount}课时 ·${module.estimatedTime}).fontSize(13).fontColor(this.isDarkMode?#d1d5db:#495057).margin({top:4})// 进度条未完成且有进度时显示if(this.getModuleProgress(module)0!ProgressService.isModuleCompleted(module.id,this.progress)){Row(){Progress({value:this.getModuleProgress(module),total:100,type:ProgressType.Linear}).width(60%).height(3).color(this.isDarkMode?#61DAFB:#0077b6).backgroundColor(this.isDarkMode?#3d3d5c:#e9ecef)Text(${this.getModuleProgress(module)}%).fontSize(11).fontColor(this.isDarkMode?#61DAFB:#0077b6).margin({left:8})}.margin({top:8})}}.alignItems(HorizontalAlign.Start).margin({left:12}).layoutWeight(1)Text(›).fontSize(20).fontColor(this.isDarkMode?#9ca3af:#6c757d)}.width(100%).padding(16).margin({left:16,right:16,bottom:8}).backgroundColor(this.isDarkMode?#282c34:#ffffff).borderRadius(12).onClick((){router.pushUrl({url:pages/ModuleDetail,params:{moduleId:module.id}});})}privategetDifficultyTitle(difficulty:string):string{consttitles:Recordstring,string{beginner: 入门,basic: 基础,intermediate: 进阶,advanced: 高级,ecosystem: 生态};returntitles[difficulty]??difficulty;}privategetModuleProgress(module:LearningModule):number{returnProgressService.getCompletionPercentage(module,this.progress);}本次课程小结通过本次课程你已经✅ 掌握了列表分组展示技巧✅ 学会了设计模块列表项✅ 实现了课程数量与时长显示✅ 了解了列表滚动优化方法✅ 完成了课程列表页面开发课后练习添加筛选功能实现按难度筛选模块添加排序功能支持按进度、课时数排序添加搜索功能在列表顶部添加搜索框下次预告第17次模块详情页面我们将开发模块详情页面页面路由与参数传递模块信息展示课程列表组件 LessonItem完成状态标记进入详情页面开发
返回列表