鸿蒙原生应用实战三诗词详情与作者天地页面——复杂数据展示与交互设计前言前两章我们完成了项目架构和首页/诗词库页面的开发。本章将聚焦于应用中数据最密集的两个页面诗词详情页PoemDetailPage.ets—— 12 套完整诗词数据、注释、背景、赏析作者天地页AuthorPage.ets—— 8 位诗人信息、代表作标签这两个页面展示了 ArkTS 中复杂数据对象的组织、折叠面板交互、计时器等高级功能。一、诗词详情页PoemDetailPage.ets1.1 数据结构设计详情页最核心的是数据结构设计。我们定义了一个包含完整信息的接口interfacePoemAnnotation{term:string;// 词语meaning:string;// 释义}interfacePoemFullData{id:number;title:string;author:string;dynasty:string;fullContent:string[];// 全文诗句数组annotations:PoemAnnotation[];// 逐词注释appreciation:string;// 名家赏析background:string;// 创作背景type:string;// 诗词类型}1.2 12 套完整数据嵌入在 App 内部直接嵌入 12 套诗词数据避免了网络请求的依赖。数据以Recordstring, PoemFullData的形式组织键为诗词 IDconstpoemsData:Recordstring,PoemFullData{1:{id:1,title:静夜思,author:李白,dynasty:唐,fullContent:[床前明月光,疑是地上霜,举头望明月,低头思故乡],annotations:[{term:静夜思,meaning:安静的夜晚产生的思绪。},{term:疑,meaning:好像仿佛。},{term:举头,meaning:抬头。}],appreciation:这首诗描绘了秋日夜晚旅居在外的游子对故乡的深切思念...,background:此诗作于唐玄宗开元十四年726年李白在扬州旅舍...,type:五言绝句},2:{/* 春晓——孟浩然 */},3:{/* 水调歌头——苏轼 */},// ... 共 12 套完整数据};1.3 路由参数接收详情页通过aboutToAppear生命周期方法接收路由参数StateWatch(onPoemIdChange)poemId:number1;StatepoemData:PoemFullDatapoemsData[1];aboutToAppear():void{constparamsrouter.getParams()asRecordstring,Object;if(paramsparams[poemId]!undefined){this.poemIdparams[poemId]asnumber;}}onPoemIdChange():void{this.poemDatapoemsData[this.poemId.toString()]||poemsData[1];}要点Watch(onPoemIdChange)确保当poemId变化时poemData自动更新。1.4 页面结构详情页从上到下包含┌──────────────────────────┐ │ ← 返回 ⭐ 收藏 ··· │ ← 顶部操作栏 ├──────────────────────────┤ │ 静 夜 思 │ ← 标题大字号字间距 │ 唐 · 李白 │ │ 五言绝句 [标签] │ ├──────────────────────────┤ │ 床前明月光 │ │ 疑是地上霜 │ ← 全文展示居中行间距 │ 举头望明月 │ │ 低头思故乡 │ ├──────────────────────────┤ │ ❤ 点赞 朗读 分享 │ ← 操作按钮组 ├──────────────────────────┤ │ 注释 │ │ 静夜思 │ 安静夜晚的思绪 │ ← 逐词注释 │ 疑 │ 好像仿佛 │ │ 举头 │ 抬头 │ ├──────────────────────────┤ │ 创作背景 [展开 ▼] │ ← 折叠面板 │ (点击展开后显示内容) │ ├──────────────────────────┤ │ 赏析 │ ← 底部 └──────────────────────────┘1.5 全文展示诗文正文居中展示每句诗单独一行设置合适的行高和字间距ForEach(this.poemData.fullContent,(line:string){Text(line).fontSize(19).fontColor($r(app.color.text_primary)).lineHeight(36)// 行高增加呼吸感.letterSpacing(2)// 字间距增强古典韵味.textAlign(TextAlign.Center).width(100%).padding({top:6})},(line:string)line)1.6 注释区域注释区域使用ForEach遍历annotations数组每行显示词语和释义ForEach(this.poemData.annotations,(ann:PoemAnnotation){Row(){Text(ann.term).fontSize(14).fontColor($r(app.color.accent_purple)).fontWeight(FontWeight.Medium)Text(ann.meaning).fontSize(13).fontColor($r(app.color.text_secondary)).margin({left:8}).layoutWeight(1)}.width(100%).alignItems(VerticalAlign.Top).padding({top:4,bottom:4})},(ann:PoemAnnotation)ann.term)1.7 折叠面板创作背景创作背景默认折叠点击展开按钮后显示。状态由isShowFull控制StateisShowFull:booleanfalse;Column(){Row(){Text( 创作背景).fontSize(16).fontWeight(FontWeight.Bold)Blank()Text(this.isShowFull?收起 ▲:展开 ▼).fontSize(12).fontColor($r(app.color.accent_purple))}.width(100%).onClick((){this.isShowFull!this.isShowFull;})// 折叠内容——只有展开时渲染if(this.isShowFull){Text(this.poemData.background).fontSize(14).fontColor($r(app.color.text_primary)).lineHeight(22).padding({top:10})}}技巧在 ArkTS 中if条件包裹的组件只有条件为 true 时才会被创建天然实现了懒加载。1.8 交互操作页面提供了多种交互// 收藏切换Text(this.isFav?⭐:☆).fontSize(22).onClick((){this.isFav!this.isFav;})// 点赞切换Row(){Text(this.isLiked?❤:).fontSize(20)Text(点赞).fontSize(13).margin({left:4})}.onClick((){this.isLiked!this.isLiked;})二、作者天地页AuthorPage.ets2.1 诗人数据我们整理了 8 位最具代表性的诗人每位包含简介、生卒年、风格标签和代表作constauthors:AuthorInfo[][{id:1,name:李白,dynasty:唐,avatar:,bio:字太白号青莲居士唐代伟大的浪漫主义诗人被后人誉为诗仙。,birthDeath:701年—762年,poemCount:1010,style:飘逸奔放,masterpieces:[静夜思,将进酒,望庐山瀑布,蜀道难,行路难]},// 杜甫、苏轼、李清照、白居易、李商隐、王维、李煜];2.2 诗人卡片设计每个诗人卡片展示丰富的信息层次BuildercreateAuthorCard(author:AuthorInfo){Column(){Row(){// Emoji 头像Text(author.avatar).fontSize(40)Column(){Row(){Text(author.name).fontSize(20).fontWeight(FontWeight.Bold)Text(author.dynasty代).fontSize(12).fontColor($r(app.color.text_secondary))}Text(author.birthDeath).fontSize(12).fontColor($r(app.color.text_secondary))Row(){Text(风格: author.style).fontSize(11).fontColor($r(app.color.accent_purple)).padding({left:6,right:6,top:2,bottom:2}).backgroundColor($r(app.color.accent_purple)15).borderRadius(4)Text( author.poemCount.toString()首).fontSize(11).margin({left:8})}}.layoutWeight(1).padding({left:14})Text().fontSize(18).fontColor($r(app.color.text_secondary))}// 人物简介最多两行Text(author.bio).fontSize(13).lineHeight(20).maxLines(2).textOverflow({overflow:TextOverflow.Ellipsis})// 代表作标签Row(){Text(代表作: ).fontSize(12)ForEach(author.masterpieces.slice(0,3),(title:string){Text(title).fontSize(12).fontColor($r(app.color.accent_purple)).padding({left:8,right:8,top:2,bottom:2}).backgroundColor($r(app.color.accent_purple)10).borderRadius(4).margin({right:6})},(title:string)title)}}.width(100%).padding(16).backgroundColor($r(app.color.bg_card)).borderRadius(16).onClick((){// 点击跳转到诗词库并自动搜索该作者router.pushUrl({url:pages/PoemListPage,params:{searchAuthor:author.name}});})}2.3 数据过滤作者页同样使用State Watch模式处理搜索和朝代筛选StateWatch(onAuthorFilterChange)searchText:string;StateWatch(onAuthorFilterChange)activeDynasty:stringall;StatefilteredAuthorsList:AuthorInfo[]authors;onAuthorFilterChange():void{letresult:AuthorInfo[]authors;if(this.searchText.length0){constkw:stringthis.searchText.toLowerCase();resultresult.filter((a:AuthorInfo)a.name.includes(kw));}if(this.activeDynasty!all){resultresult.filter((a:AuthorInfo)a.dynastythis.activeDynasty);}this.filteredAuthorsListresult;}2.4 Builder 参数化筛选标签因为 Builder 内不能声明变量我们通过参数传递来避免此限制// 在 build() 中直接调用 Builder 方法Row(){this.dynastyFilter(all,全部,0)this.dynastyFilter(唐,唐代,1)this.dynastyFilter(宋,宋代,2)this.dynastyFilter(五代,五代,3)}BuilderdynastyFilter(opt:string,label:string,idx:number){Text(label).fontSize(13).fontColor(optthis.activeDynasty?Color.White:$r(app.color.text_secondary)).padding({left:16,right:16,top:6,bottom:6}).backgroundColor(optthis.activeDynasty?$r(app.color.accent_purple):$r(app.color.bg_card)).borderRadius(16).margin({right:8}).onClick((){this.activeDynastyopt;})}三、组件复用最佳实践3.1 底部导航栏的复用所有页面共享同一套底部导航栏。为了避免重复代码每个页面都定义了自己的createBottomNavBuilder通过参数activePage标识当前高亮项BuildercreateBottomNav(activePage:string){this.renderNavBar(activePage)}BuilderrenderNavBar(activePage:string):void{Row(){this.navItem(,首页,home,activePage,pages/Index)this.navItem(,诗词库,list,activePage,pages/PoemListPage)this.navItem(,作者,author,activePage,pages/AuthorPage)this.navItem(⭐,收藏,collection,activePage,pages/CollectionPage)}.width(100%).height(60).backgroundColor($r(app.color.bg_card)).shadow({radius:8,color:#15000000,offsetX:0,offsetY:-2})}BuildernavItem(icon:string,label:string,page:string,activePage:string,route:string){Column(){Text(icon).fontSize(22)Text(label).fontSize(10).fontColor(pageactivePage?$r(app.color.accent_purple):$r(app.color.text_secondary)).margin({top:2})}.layoutWeight(1).alignItems(HorizontalAlign.Center).onClick((){if(page!activePage){router.pushUrl({url:route});}})}小结本章完成了诗词详情页和作者天地页的开发核心内容包括12 套完整诗词数据的组织和访问折叠面板交互实现诗人卡片的多层次信息展示Builder 参数化设计避免变量声明限制跨页面跳转时自动搜索作者下一章我们将完成收藏页面和全局底部导航的整合并确保所有页面之间的无缝跳转。【系列目录】一项目初始化与架构设计二首页与诗词库页面开发三诗词详情与作者天地页面开发 ← 本文四收藏页面与底部导航实现五编译调试与问题修复经验
鸿蒙原生应用实战(三):诗词详情与作者天地页面——复杂数据展示与交互设计
发布时间:2026/6/8 14:38:15
鸿蒙原生应用实战三诗词详情与作者天地页面——复杂数据展示与交互设计前言前两章我们完成了项目架构和首页/诗词库页面的开发。本章将聚焦于应用中数据最密集的两个页面诗词详情页PoemDetailPage.ets—— 12 套完整诗词数据、注释、背景、赏析作者天地页AuthorPage.ets—— 8 位诗人信息、代表作标签这两个页面展示了 ArkTS 中复杂数据对象的组织、折叠面板交互、计时器等高级功能。一、诗词详情页PoemDetailPage.ets1.1 数据结构设计详情页最核心的是数据结构设计。我们定义了一个包含完整信息的接口interfacePoemAnnotation{term:string;// 词语meaning:string;// 释义}interfacePoemFullData{id:number;title:string;author:string;dynasty:string;fullContent:string[];// 全文诗句数组annotations:PoemAnnotation[];// 逐词注释appreciation:string;// 名家赏析background:string;// 创作背景type:string;// 诗词类型}1.2 12 套完整数据嵌入在 App 内部直接嵌入 12 套诗词数据避免了网络请求的依赖。数据以Recordstring, PoemFullData的形式组织键为诗词 IDconstpoemsData:Recordstring,PoemFullData{1:{id:1,title:静夜思,author:李白,dynasty:唐,fullContent:[床前明月光,疑是地上霜,举头望明月,低头思故乡],annotations:[{term:静夜思,meaning:安静的夜晚产生的思绪。},{term:疑,meaning:好像仿佛。},{term:举头,meaning:抬头。}],appreciation:这首诗描绘了秋日夜晚旅居在外的游子对故乡的深切思念...,background:此诗作于唐玄宗开元十四年726年李白在扬州旅舍...,type:五言绝句},2:{/* 春晓——孟浩然 */},3:{/* 水调歌头——苏轼 */},// ... 共 12 套完整数据};1.3 路由参数接收详情页通过aboutToAppear生命周期方法接收路由参数StateWatch(onPoemIdChange)poemId:number1;StatepoemData:PoemFullDatapoemsData[1];aboutToAppear():void{constparamsrouter.getParams()asRecordstring,Object;if(paramsparams[poemId]!undefined){this.poemIdparams[poemId]asnumber;}}onPoemIdChange():void{this.poemDatapoemsData[this.poemId.toString()]||poemsData[1];}要点Watch(onPoemIdChange)确保当poemId变化时poemData自动更新。1.4 页面结构详情页从上到下包含┌──────────────────────────┐ │ ← 返回 ⭐ 收藏 ··· │ ← 顶部操作栏 ├──────────────────────────┤ │ 静 夜 思 │ ← 标题大字号字间距 │ 唐 · 李白 │ │ 五言绝句 [标签] │ ├──────────────────────────┤ │ 床前明月光 │ │ 疑是地上霜 │ ← 全文展示居中行间距 │ 举头望明月 │ │ 低头思故乡 │ ├──────────────────────────┤ │ ❤ 点赞 朗读 分享 │ ← 操作按钮组 ├──────────────────────────┤ │ 注释 │ │ 静夜思 │ 安静夜晚的思绪 │ ← 逐词注释 │ 疑 │ 好像仿佛 │ │ 举头 │ 抬头 │ ├──────────────────────────┤ │ 创作背景 [展开 ▼] │ ← 折叠面板 │ (点击展开后显示内容) │ ├──────────────────────────┤ │ 赏析 │ ← 底部 └──────────────────────────┘1.5 全文展示诗文正文居中展示每句诗单独一行设置合适的行高和字间距ForEach(this.poemData.fullContent,(line:string){Text(line).fontSize(19).fontColor($r(app.color.text_primary)).lineHeight(36)// 行高增加呼吸感.letterSpacing(2)// 字间距增强古典韵味.textAlign(TextAlign.Center).width(100%).padding({top:6})},(line:string)line)1.6 注释区域注释区域使用ForEach遍历annotations数组每行显示词语和释义ForEach(this.poemData.annotations,(ann:PoemAnnotation){Row(){Text(ann.term).fontSize(14).fontColor($r(app.color.accent_purple)).fontWeight(FontWeight.Medium)Text(ann.meaning).fontSize(13).fontColor($r(app.color.text_secondary)).margin({left:8}).layoutWeight(1)}.width(100%).alignItems(VerticalAlign.Top).padding({top:4,bottom:4})},(ann:PoemAnnotation)ann.term)1.7 折叠面板创作背景创作背景默认折叠点击展开按钮后显示。状态由isShowFull控制StateisShowFull:booleanfalse;Column(){Row(){Text( 创作背景).fontSize(16).fontWeight(FontWeight.Bold)Blank()Text(this.isShowFull?收起 ▲:展开 ▼).fontSize(12).fontColor($r(app.color.accent_purple))}.width(100%).onClick((){this.isShowFull!this.isShowFull;})// 折叠内容——只有展开时渲染if(this.isShowFull){Text(this.poemData.background).fontSize(14).fontColor($r(app.color.text_primary)).lineHeight(22).padding({top:10})}}技巧在 ArkTS 中if条件包裹的组件只有条件为 true 时才会被创建天然实现了懒加载。1.8 交互操作页面提供了多种交互// 收藏切换Text(this.isFav?⭐:☆).fontSize(22).onClick((){this.isFav!this.isFav;})// 点赞切换Row(){Text(this.isLiked?❤:).fontSize(20)Text(点赞).fontSize(13).margin({left:4})}.onClick((){this.isLiked!this.isLiked;})二、作者天地页AuthorPage.ets2.1 诗人数据我们整理了 8 位最具代表性的诗人每位包含简介、生卒年、风格标签和代表作constauthors:AuthorInfo[][{id:1,name:李白,dynasty:唐,avatar:,bio:字太白号青莲居士唐代伟大的浪漫主义诗人被后人誉为诗仙。,birthDeath:701年—762年,poemCount:1010,style:飘逸奔放,masterpieces:[静夜思,将进酒,望庐山瀑布,蜀道难,行路难]},// 杜甫、苏轼、李清照、白居易、李商隐、王维、李煜];2.2 诗人卡片设计每个诗人卡片展示丰富的信息层次BuildercreateAuthorCard(author:AuthorInfo){Column(){Row(){// Emoji 头像Text(author.avatar).fontSize(40)Column(){Row(){Text(author.name).fontSize(20).fontWeight(FontWeight.Bold)Text(author.dynasty代).fontSize(12).fontColor($r(app.color.text_secondary))}Text(author.birthDeath).fontSize(12).fontColor($r(app.color.text_secondary))Row(){Text(风格: author.style).fontSize(11).fontColor($r(app.color.accent_purple)).padding({left:6,right:6,top:2,bottom:2}).backgroundColor($r(app.color.accent_purple)15).borderRadius(4)Text( author.poemCount.toString()首).fontSize(11).margin({left:8})}}.layoutWeight(1).padding({left:14})Text().fontSize(18).fontColor($r(app.color.text_secondary))}// 人物简介最多两行Text(author.bio).fontSize(13).lineHeight(20).maxLines(2).textOverflow({overflow:TextOverflow.Ellipsis})// 代表作标签Row(){Text(代表作: ).fontSize(12)ForEach(author.masterpieces.slice(0,3),(title:string){Text(title).fontSize(12).fontColor($r(app.color.accent_purple)).padding({left:8,right:8,top:2,bottom:2}).backgroundColor($r(app.color.accent_purple)10).borderRadius(4).margin({right:6})},(title:string)title)}}.width(100%).padding(16).backgroundColor($r(app.color.bg_card)).borderRadius(16).onClick((){// 点击跳转到诗词库并自动搜索该作者router.pushUrl({url:pages/PoemListPage,params:{searchAuthor:author.name}});})}2.3 数据过滤作者页同样使用State Watch模式处理搜索和朝代筛选StateWatch(onAuthorFilterChange)searchText:string;StateWatch(onAuthorFilterChange)activeDynasty:stringall;StatefilteredAuthorsList:AuthorInfo[]authors;onAuthorFilterChange():void{letresult:AuthorInfo[]authors;if(this.searchText.length0){constkw:stringthis.searchText.toLowerCase();resultresult.filter((a:AuthorInfo)a.name.includes(kw));}if(this.activeDynasty!all){resultresult.filter((a:AuthorInfo)a.dynastythis.activeDynasty);}this.filteredAuthorsListresult;}2.4 Builder 参数化筛选标签因为 Builder 内不能声明变量我们通过参数传递来避免此限制// 在 build() 中直接调用 Builder 方法Row(){this.dynastyFilter(all,全部,0)this.dynastyFilter(唐,唐代,1)this.dynastyFilter(宋,宋代,2)this.dynastyFilter(五代,五代,3)}BuilderdynastyFilter(opt:string,label:string,idx:number){Text(label).fontSize(13).fontColor(optthis.activeDynasty?Color.White:$r(app.color.text_secondary)).padding({left:16,right:16,top:6,bottom:6}).backgroundColor(optthis.activeDynasty?$r(app.color.accent_purple):$r(app.color.bg_card)).borderRadius(16).margin({right:8}).onClick((){this.activeDynastyopt;})}三、组件复用最佳实践3.1 底部导航栏的复用所有页面共享同一套底部导航栏。为了避免重复代码每个页面都定义了自己的createBottomNavBuilder通过参数activePage标识当前高亮项BuildercreateBottomNav(activePage:string){this.renderNavBar(activePage)}BuilderrenderNavBar(activePage:string):void{Row(){this.navItem(,首页,home,activePage,pages/Index)this.navItem(,诗词库,list,activePage,pages/PoemListPage)this.navItem(,作者,author,activePage,pages/AuthorPage)this.navItem(⭐,收藏,collection,activePage,pages/CollectionPage)}.width(100%).height(60).backgroundColor($r(app.color.bg_card)).shadow({radius:8,color:#15000000,offsetX:0,offsetY:-2})}BuildernavItem(icon:string,label:string,page:string,activePage:string,route:string){Column(){Text(icon).fontSize(22)Text(label).fontSize(10).fontColor(pageactivePage?$r(app.color.accent_purple):$r(app.color.text_secondary)).margin({top:2})}.layoutWeight(1).alignItems(HorizontalAlign.Center).onClick((){if(page!activePage){router.pushUrl({url:route});}})}小结本章完成了诗词详情页和作者天地页的开发核心内容包括12 套完整诗词数据的组织和访问折叠面板交互实现诗人卡片的多层次信息展示Builder 参数化设计避免变量声明限制跨页面跳转时自动搜索作者下一章我们将完成收藏页面和全局底部导航的整合并确保所有页面之间的无缝跳转。【系列目录】一项目初始化与架构设计二首页与诗词库页面开发三诗词详情与作者天地页面开发 ← 本文四收藏页面与底部导航实现五编译调试与问题修复经验