阅读时长:约 19 分钟 | 难度:★★★★☆ | 篇章:第 4 篇 · 二十八星宿模块
对应源码:entry/src/main/ets/pages/mansion/MansionDetailPage.ets
前言
星宿详情页是玄象项目星宿模块的"内容深度"体现。用户从列表页点击某个星宿,进入详情页查看该星宿的金色 Canvas 星图、四象属性、五行属性、分野、星官、文化解释等完整信息。本篇将深入剖析玄象项目星宿详情页的实现:从router.getParams参数接收、MansionData.getMansionByName数据查询、@Builder InfoCard信息卡片网格、Scroll + Column可滚动布局,到Canvas星宿插图绘制。掌握这套详情页实现方法论,您就能为任何 HarmonyOS 应用打造深度内容展示页。
提示:详情页是"内容消费"的核心场景。玄象项目星宿详情页通过金边卡片网格 + Canvas 星图 + 文化解释三部分,让用户沉浸式了解每个星宿。
一、MansionDetailPage 完整布局
1.1 页面结构
build(){Column(){// 顶部导航栏Row(){...}// 可滚动内容区Scroll(){Column({space:20}){// 星宿插图 CanvasCanvas(this.mansionIllustrationContext).width('100%').height(200)// 四象标注Text("东方苍龙第一宿")// 信息卡片网格Grid(){GridItem(){this.InfoCard('象','龙角','')}GridItem(){this.InfoCard('分野','','郑国')}GridItem(){this.InfoCard('五行','木','木')}GridItem(){this.InfoCard('对应','','春季')}GridItem(){this.InfoCard('星官','','角、平道、天田')}}// 文化解释卡片Column(){Text('文化解释')Text(this.mansion?.description)}}}.layoutWeight(1)}}1.2 数据加载
aboutToAppear():void{constparams=router.getParams()asRecord<string,string>;constname=params['mansionName']||'角宿';this.mansion=MansionData.getMansionByName(name);}二、InfoCard 信息卡片网格
2.1 @Builder InfoCard
@BuilderInfoCard(title:string,icon:string,value:string){Column({space:8}){Text(title).fontSize(16).fontWeight(FontWeight.Bold).fontColor(Colors.PRIMARY_GOLD)if(icon){Text(icon).fontSize(32)}Text(value).fontSize(14).fontColor(Colors.TEXT_PRIMARY)}.width('100%').height(100).justifyContent(FlexAlign.Center).backgroundColor(Colors.BG_CARD).border({width:1,color:Colors.BG_CARD_BORDER,radius:12}).borderRadius(12)}2.2 网格布局
Grid(){GridItem(){this.InfoCard('象',this.mansion?.animal||'','龙角')}GridItem(){this.InfoCard('分野','',this.mansion?.fenYe||'')}GridItem(){this.InfoCard('五行',this.mansion?.wuXing||'',this.mansion?.wuXing||'')}GridItem(){this.InfoCard('对应','',this.mansion?.season||'')}GridItem(){this.InfoCard('星官','',this.mansion?.xingGuan||'')}}.columnsTemplate('1fr 1fr 1fr').rowsGap(12).columnsGap(12).width('100%')三、Canvas 星宿插图
3.1 绘制方法
privatedrawMansionIllustration=(canvas:CanvasRenderingContext2D,w:number,h:number)=>{// 背景canvas.fillStyle='#0D1520';canvas.fillRect(0,0,w,h);// 星星for(leti=0;i<50;i++){canvas.fillStyle=`rgba(255, 255, 220,${Math.random()*0.5+0.2})`;canvas.beginPath();canvas.arc(Math.random()*w,Math.random()*h,Math.random()*1.5+0.5,0,Math.PI*2);canvas.fill();}// 星宿连线if(this.mansion){canvas.strokeStyle=Colors.PRIMARY_GOLD;canvas.lineWidth=1.5;canvas.beginPath();constpoints=[[w*0.2,h*0.6],[w*0.35,h*0.4],[w*0.5,h*0.3],[w*0.65,h*0.35],[w*0.8,h*0.5]];canvas.moveTo(points[0][0],points[0][1]);for(leti=1;i<points.length;i++){canvas.lineTo(points[i][0],points[i][1]);}canvas.stroke();for(constpofpoints){canvas.fillStyle='#F0D078';canvas.beginPath();canvas.arc(p[0],p[1],4,0,Math.PI*2);canvas.fill();}}}四、文化解释卡片
4.1 卡片结构
Column({space:12}){Text('文化解释').fontSize(20).fontWeight(FontWeight.Bold).fontColor(Colors.PRIMARY_GOLD).width('100%')Text(this.mansion?.description||'').fontSize(15).fontColor(Colors.TEXT_PRIMARY).lineHeight(24).width('100%')}.width('100%').padding(16).backgroundColor(Colors.BG_CARD).border({width:1,color:Colors.PRIMARY_GOLD,radius:12}).borderRadius(12)五、详情页设计总结
5.1 页面结构
| 区域 | 组件 | 内容 |
|---|---|---|
| 顶部导航 | Row | 返回 + 标题 |
| 星宿插图 | Canvas | 星空 + 星点连线 |
| 四象标注 | Text | “东方苍龙第一宿” |
| 信息网格 | Grid | 5 个 InfoCard |
| 文化解释 | Column | 标题 + 描述文本 |
5.2 数据流
列表页点击 → router.pushUrl → MansionDetailPage ↓ aboutToAppear → router.getParams → getMansionByName ↓ @State mansion → UI 渲染六、详情页的数据安全与容错
6.1 参数验证
aboutToAppear():void{constparams=router.getParams()asRecord<string,string>;if(!params||!params['mansionName']){// 无参数时默认显示角宿this.mansion=MansionData.getMansionByName('角宿');return;}this.mansion=MansionData.getMansionByName(params['mansionName']);if(!this.mansion){// 未找到星宿时默认显示角宿this.mansion=MansionData.getMansionByName('角宿');}}6.2 InfoCard 的组件化设计
| 卡片字段 | 数据来源 | 展示方式 |
|---|---|---|
| 象 | mansion.animal | 文字 + 图标 |
| 分野 | mansion.fenYe | 文字 |
| 五行 | mansion.wuXing | 文字 + 颜色 |
| 对应 | mansion.season | 文字 |
| 星官 | mansion.xingGuan | 文字 |
6.3 详情页的视觉设计规范
- 信息分层:插图(视觉层)→ 属性网格(信息层)→ 文化解释(内容层)
- 一致性:金边卡片样式与全应用保持一致
- 可读性:
lineHeight(24)确保长文本的阅读舒适度
七、详情页的扩展方向
7.1 添加滚动浏览
Scroll(){Column({space:20}){// 星宿插图// 信息卡片网格// 文化解释// 相关星宿推荐}}.layoutWeight(1)7.2 添加相关星宿推荐
@BuilderRelatedMansions(){Column({space:12}){Text('同象星宿').fontSize(18).fontColor(Colors.PRIMARY_GOLD)Row({space:8}){ForEach(this.relatedMansions,(m:MansionInfo)=>{Text(m.name).fontSize(14).fontColor(Colors.TEXT_PRIMARY).padding(8).backgroundColor(Colors.BG_CARD).borderRadius(8).onClick(()=>{this.mansion=m;})})}}}7.3 详情页的响应式适配
| 屏幕宽度 | 布局策略 | 网格列数 |
|---|---|---|
| < 360vp | 紧凑布局 | 2 列 |
| 360~720vp | 标准布局 | 3 列 |
| > 720vp | 宽松布局 | 4 列 |
八、详情页的交互优化
8.1 详情页的加载状态
@StateisLoading:boolean=true;aboutToAppear():void{this.isLoading=true;constparams=router.getParams()asRecord<string,string>;constname=params['mansionName']||'角宿';// 模拟数据加载延迟setTimeout(()=>{this.mansion=MansionData.getMansionByName(name);this.isLoading=false;},300);}build(){if(this.isLoading){// 加载中状态LoadingProgress().color(Colors.PRIMARY_GOLD).width(50).height(50)}else{// 正常内容this.buildContent();}}8.2 详情页的分享功能
@BuilderShareButton(){Text('分享').fontSize(14).fontColor(Colors.PRIMARY_GOLD).onClick(()=>{// 调用系统分享constshareData={title:`星宿:${this.mansion?.name}`,text:this.mansion?.description||''};// 系统分享API})}8.3 详情页的收藏功能
| 功能 | 实现方式 | 存储方式 |
|---|---|---|
| 收藏星宿 | @State isFavorited | preferences |
| 最近浏览 | @State recentList | relationalStore |
| 分享星宿 | 系统分享API | 临时数据 |
九、详情页的视觉设计规范
9.1 信息层级
玄象项目星宿详情页的信息层级遵循"从上到下、从宏观到微观"的原则:
- 视觉层:星宿插图 Canvas(200px 高)
- 标识层:四象标注(“东方苍龙第一宿”)
- 信息层:5 个属性卡片网格
- 内容层:文化解释文本
9.2 色彩规范
| 元素 | 颜色 | 用途 |
|---|---|---|
| 插图背景 | #0D1520 | 星空深色背景 |
| 属性卡片 | Colors.BG_CARD | 卡片背景 |
| 标题文字 | Colors.PRIMARY_GOLD | 金色强调 |
| 正文文字 | Colors.TEXT_PRIMARY | 白色正文 |
| 分隔线 | Colors.BG_CARD_BORDER | 灰色分割线 |
9.3 详情页的排版规范
- 插图区域:200px 高度,深色背景衬托金色星点
- 四象标注:字号 16,居中显示,灰色文字
- 信息卡片:3 列网格,每项 100px 高度
- 文化解释:字号 15,lineHeight 24,阅读舒适
- 页面内边距:左右 16vp,上下 20vp
十、总结与最佳实践
10.1 详情页开发要点
- 参数安全:始终检查
router.getParams()的返回值 - 数据容错:查询不到数据时设置默认值
- 加载体验:数据加载时显示 LoadingProgress
- 视觉层次:插画→属性→文字,逐层递进
- 响应式适配:不同屏幕调整网格列数
10.2 详情页开发常见问题
| 问题 | 解决方案 |
|---|---|
| 参数获取失败 | 使用默认值兜底 |
| 数据加载慢 | 添加 LoadingProgress 加载态 |
| 图片资源缺失 | 使用 Canvas 动态绘制替代 |
| 布局错乱 | 使用 Scroll + layoutWeight 弹性布局 |
总结
本篇以玄象项目星宿详情页为蓝本,深入剖析了 ArkUI 详情页实现:从router.getParams参数接收、MansionData.getMansionByName数据查询、@Builder InfoCard信息卡片网格,到Canvas星宿插图绘制与lineHeight文本行高控制。掌握这套详情页实现方法论,您就能为任何 HarmonyOS 应用打造深度内容展示页。
下一篇:《34 · StarTerritoryPage 星野分野:分封列国与星宿对应关系图》,将带您深入玄象项目星野分野页的实现。
如果这篇文章对你有帮助,欢迎点赞👍、收藏⭐、关注🔔,你的支持是我持续创作的动力!
相关资源:
- HarmonyOS 官方文档:router.getParams
- HarmonyOS 官方文档:Grid 组件
- 开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net