上一篇我们拆解了维系首页的布局。这篇继续看第二个 Tab——档案。“维系页解决的是我现在该做什么”“档案页解决的是我关心的人是谁”。两个页面的布局思路完全不同维系页是多种卡片的混合拼图档案页则是同一种卡片的纵向重复。布局越单一反而越考验单张卡片的设计。一、页面全貌对应代码骨架BuilderPeopleTab(){Scroll(){Column(){Row(){Text(人物档案)Blank()Text( 新增档案)}Text(为每个人建立可维护的关系画像)this.PersonDetailCard(...)this.PersonDetailCard(...)this.PersonDetailCard(...)}.width(100%).padding({left:24,right:24,top:0,bottom:140})}.scrollBar(BarState.Off).height(100%).width(100%).backgroundColor(#F9F7F2)}和维系页一样外层是ScrollColumn左右 24vp 内边距底部 140vp 给导航栏留白。这些不再重复这篇的重点是PersonDetailCard 这张卡片。二、标题行左标题右操作Row(){Text(人物档案).fontSize(26).fontWeight(FontWeight.Bold).fontColor(#2C2723)Blank()Text( 新增档案).fontSize(15).fontColor(#8B7355)}.width(100%).alignItems(VerticalAlign.Center).margin({top:20,bottom:6}).padding({left:2,right:2})和维系页的问候区域一样RowBlank()实现左右分布。但这里有一个额外细节2.1 alignItems(VerticalAlign.Center).alignItems(VerticalAlign.Center)标题是 26 号字操作按钮是 15 号字高度差很大。如果不设居中对齐按钮会贴着标题底部视觉上偏下。VerticalAlign.Center让两者垂直居中看起来更平衡。2.2 微调 padding.padding({left:2,right:2})2vp 的左右内边距让标题行和下方副标题有微小的错位。这种不完美对齐反而让页面不那么机械。三、副标题一句话说明页面用途Text(为每个人建立可维护的关系画像).fontSize(14).fontColor(#A0988C).width(100%).margin({bottom:24})14 号字、灰色#A0988C视觉上退到最远处。它的作用不是被阅读而是让用户第一次进入页面时花 0.5 秒理解这个页面是干什么的。四、PersonDetailCard整页的核心从上到下三个区域头部信息、分隔线、备注与标签。BuilderPersonDetailCard(initial:string,name:string,relation:string,intimacy:number,note:string,tags:string[],lastContactDays:number,accentColor:string){Column(){// 头部头像 姓名/关系/亲密度Row(){...}.width(100%)// 分隔线Divider().color(#F0EBE3).margin({top:18,bottom:18})// 备注Text(note).fontSize(14).lineHeight(22).fontColor(#7A7066).width(100%)// 标签Flex({wrap:FlexWrap.Wrap}){...}.width(100%)}.alignItems(HorizontalAlign.Start).padding(22).borderRadius(22).backgroundColor(#FFFFFF).shadow({radius:14,color:#1A000007,offsetY:4}).margin({bottom:16})}接下来逐层拆开。五、头部头像 右侧信息头部是一个Row左侧头像、右侧文字信息Row(){// 头像Column(){Text(initial).fontSize(22).fontWeight(FontWeight.Bold).fontColor(#FFFFFF)}.width(56).height(56).borderRadius(28).justifyContent(FlexAlign.Center).backgroundColor(accentColor)// 右侧信息Column(){Row(){...}// 第一行姓名 关系标签Row(){...}// 第二行亲密度 上次沟通}.alignItems(HorizontalAlign.Start).layoutWeight(1).margin({left:16})}.width(100%)5.1 头像56×56 圆形.width(56).height(56).borderRadius(28)比维系页的头像40×40 和 50×50都大。因为档案页的人物信息更详细头像作为视觉锚点需要更大更醒目。borderRadius设为宽度的一半28形成正圆。5.2 头像背景色由外部传入.backgroundColor(accentColor)accentColor是卡片的参数之一不同人物用不同颜色人物accentColor视觉感受王奕辰#8B7355经典棕林阿姨#9B8578温暖棕陈若宁#7A8B7A沉稳绿这个颜色不仅用在头像上还用在关系标签和亲密度星标上形成一张卡片一个主色调的效果。5.3 右侧 Column 用 layoutWeight(1).layoutWeight(1).margin({left:16})头像固定 56vp右侧文字用layoutWeight(1)填满剩余宽度。margin({ left: 16 })控制头像和文字之间的间距比维系页的 12-14vp 稍大因为这张卡片整体尺寸更大间距也要相应放大。六、第一行姓名 关系标签Row(){Text(name).fontSize(20).fontWeight(FontWeight.Bold).fontColor(#2C2723)Text(relation).fontSize(12).fontColor(accentColor).padding({left:10,right:10,top:4,bottom:4}).borderRadius(8).backgroundColor(#FAF6EF).margin({left:10})}6.1 关系标签的配色.fontColor(accentColor).backgroundColor(#FAF6EF)文字颜色用accentColor和头像同色背景用#FAF6EF极浅的暖色。这样标签和头像形成色彩呼应同时浅底保证文字可读性。6.2 药丸标签的 padding.padding({left:10,right:10,top:4,bottom:4}).borderRadius(8)上下 4、左右 10 的内边距配合 8vp 圆角形成一个小药丸形状。字号 12 配合这个尺寸视觉上紧凑但不拥挤。七、第二行亲密度星标 上次沟通Row(){ForEach([1,2,3,4,5],(star:number){Text(starintimacy?★:☆).fontSize(13).fontColor(starintimacy?#D4B896:#E0D8CC).margin({right:2})})Text(· 上次沟通${lastContactDays}天前).fontSize(13).fontColor(#B5ADA2).margin({left:8})}.margin({top:6})★★★★☆ · 上次沟通 12 天前7.1 用 ForEach 渲染星标ForEach([1,2,3,4,5],(star:number){Text(starintimacy?★:☆)})5 颗星intimacy是几就亮几颗。ForEach遍历[1,2,3,4,5]每次判断当前星星是否应该亮起。7.2 两色区分亮暗星.fontColor(starintimacy?#D4B896:#E0D8CC)亮星用金色#D4B896暗星用浅灰#E0D8CC。两种颜色饱和度都不高不会抢夺姓名的视觉焦点。7.3 星标和文字之间用 · 分隔Text(· 上次沟通${lastContactDays}天前).margin({left:8})中圆点·作为星标和文字的分隔符比竖线|更柔和。margin({ left: 8 })让分隔符和星标之间有 8vp 的间距。八、分隔线Divider().color(#F0EBE3).margin({top:18,bottom:18})头部信息和备注之间用一条浅色分隔线隔开。#F0EBE3是暖灰色和页面整体色调一致。上下各 18vp 的间距让分隔线两侧都有足够的呼吸空间。九、备注文字Text(note).fontSize(14).lineHeight(22).fontColor(#7A7066).width(100%)14 号字、22 行高行间距约 8vp阅读舒适。#7A7066是中灰色比主文字#2C2723浅比辅助文字#B5ADA2深适合这种重要但不是最醒目的信息。十、标签区Flex 自动换行Flex({wrap:FlexWrap.Wrap}){ForEach(tags,(tag:string){Text(tag).fontSize(12).fontColor(#9A8E82).padding({left:12,right:12,top:6,bottom:6}).borderRadius(14).backgroundColor(#F7F4EE).margin({top:14,right:8})})}.width(100%)10.1 为什么用 Flex 而不是 RowRow不会自动换行。如果标签太多会超出屏幕宽度。Flex({ wrap: FlexWrap.Wrap })会在空间不足时自动换行标签数量从 1 到 N 都能正常展示。10.2 标签的间距控制.margin({top:14,right:8})只设了top和right没有设bottom和left。这样水平方向标签之间靠right: 8分隔。垂直方向换行后靠top: 14分隔。第一行顶部不需要额外间距因为备注文字已经提供了空间。10.3 标签样式.fontSize(12).fontColor(#9A8E82).padding({left:12,right:12,top:6,bottom:6}).borderRadius(14).backgroundColor(#F7F4EE)和关系标签不同这里的标签用灰色#9A8E82 浅底#F7F4EE视觉上更轻。因为一张卡片只有一个关系标签重要但可能有多个特征标签咖啡爱好者、帮过我大忙…特征标签不应该太抢眼。borderRadius(14)配合padding形成圆角药丸和关系标签风格统一。十一、卡片外壳.alignItems(HorizontalAlign.Start).padding(22).borderRadius(22).backgroundColor(#FFFFFF).shadow({radius:14,color:#1A000007,offsetY:4}).margin({bottom:16})11.1 padding 22比维系页的提醒卡片padding 18和久未联系卡片padding 18都大。因为这张卡片信息量更大需要更多内边距让内容不显得拥挤。11.2 borderRadius 22圆角也更大提醒卡片 20、久未联系卡片 18。卡片越大圆角也应该越大否则会显得生硬。11.3 阴影最轻.shadow({radius:14,color:#1A000007,offsetY:4})#1A000007的最后两位07表示约 3% 不透明度是整页最轻的阴影。因为档案页只有一种卡片不需要通过阴影强弱来区分层级——所有卡片地位平等。十二、和维系页的对比两个页面用了相同的外层结构Scroll Column但卡片设计思路完全不同对比项维系页档案页卡片种类3 种提醒、久未联系、统计1 种PersonDetailCard卡片方向提醒横向、久未联系横向全部纵向信息密度提醒卡片高、久未联系低统一中等密度头像尺寸40 / 5056卡片圆角20 / 18 / 2422卡片内边距18 / 18 / 2622分隔线无有头部和备注之间核心区别维系页用不同卡片表达不同优先级档案页用同一卡片表达平等关系。十三、总结这篇我们拆解了档案页面的 UI 布局核心要点单一卡片纵向重复页面结构极简重点全在卡片设计上。头像 layoutWeight固定头像宽度右侧信息弹性填充。accentColor 贯穿卡片头像、关系标签、星标共用一个主色一张卡片一个色调。ForEach 渲染星标5 颗星根据亲密度动态亮灭两色区分。Flex 自动换行标签标签数量不确定时Flex({ wrap: FlexWrap.Wrap })是最稳妥的方案。分隔线划分区域头部信息和备注之间用浅色 Divider 隔开比留白更有结构感。尺寸随卡片放大头像 56、padding 22、borderRadius 22比小卡片都大一圈。
【HarmonyOS 6】“档案“页面的UI布局拆解
上一篇我们拆解了维系首页的布局。这篇继续看第二个 Tab——档案。“维系页解决的是我现在该做什么”“档案页解决的是我关心的人是谁”。两个页面的布局思路完全不同维系页是多种卡片的混合拼图档案页则是同一种卡片的纵向重复。布局越单一反而越考验单张卡片的设计。一、页面全貌对应代码骨架BuilderPeopleTab(){Scroll(){Column(){Row(){Text(人物档案)Blank()Text( 新增档案)}Text(为每个人建立可维护的关系画像)this.PersonDetailCard(...)this.PersonDetailCard(...)this.PersonDetailCard(...)}.width(100%).padding({left:24,right:24,top:0,bottom:140})}.scrollBar(BarState.Off).height(100%).width(100%).backgroundColor(#F9F7F2)}和维系页一样外层是ScrollColumn左右 24vp 内边距底部 140vp 给导航栏留白。这些不再重复这篇的重点是PersonDetailCard 这张卡片。二、标题行左标题右操作Row(){Text(人物档案).fontSize(26).fontWeight(FontWeight.Bold).fontColor(#2C2723)Blank()Text( 新增档案).fontSize(15).fontColor(#8B7355)}.width(100%).alignItems(VerticalAlign.Center).margin({top:20,bottom:6}).padding({left:2,right:2})和维系页的问候区域一样RowBlank()实现左右分布。但这里有一个额外细节2.1 alignItems(VerticalAlign.Center).alignItems(VerticalAlign.Center)标题是 26 号字操作按钮是 15 号字高度差很大。如果不设居中对齐按钮会贴着标题底部视觉上偏下。VerticalAlign.Center让两者垂直居中看起来更平衡。2.2 微调 padding.padding({left:2,right:2})2vp 的左右内边距让标题行和下方副标题有微小的错位。这种不完美对齐反而让页面不那么机械。三、副标题一句话说明页面用途Text(为每个人建立可维护的关系画像).fontSize(14).fontColor(#A0988C).width(100%).margin({bottom:24})14 号字、灰色#A0988C视觉上退到最远处。它的作用不是被阅读而是让用户第一次进入页面时花 0.5 秒理解这个页面是干什么的。四、PersonDetailCard整页的核心从上到下三个区域头部信息、分隔线、备注与标签。BuilderPersonDetailCard(initial:string,name:string,relation:string,intimacy:number,note:string,tags:string[],lastContactDays:number,accentColor:string){Column(){// 头部头像 姓名/关系/亲密度Row(){...}.width(100%)// 分隔线Divider().color(#F0EBE3).margin({top:18,bottom:18})// 备注Text(note).fontSize(14).lineHeight(22).fontColor(#7A7066).width(100%)// 标签Flex({wrap:FlexWrap.Wrap}){...}.width(100%)}.alignItems(HorizontalAlign.Start).padding(22).borderRadius(22).backgroundColor(#FFFFFF).shadow({radius:14,color:#1A000007,offsetY:4}).margin({bottom:16})}接下来逐层拆开。五、头部头像 右侧信息头部是一个Row左侧头像、右侧文字信息Row(){// 头像Column(){Text(initial).fontSize(22).fontWeight(FontWeight.Bold).fontColor(#FFFFFF)}.width(56).height(56).borderRadius(28).justifyContent(FlexAlign.Center).backgroundColor(accentColor)// 右侧信息Column(){Row(){...}// 第一行姓名 关系标签Row(){...}// 第二行亲密度 上次沟通}.alignItems(HorizontalAlign.Start).layoutWeight(1).margin({left:16})}.width(100%)5.1 头像56×56 圆形.width(56).height(56).borderRadius(28)比维系页的头像40×40 和 50×50都大。因为档案页的人物信息更详细头像作为视觉锚点需要更大更醒目。borderRadius设为宽度的一半28形成正圆。5.2 头像背景色由外部传入.backgroundColor(accentColor)accentColor是卡片的参数之一不同人物用不同颜色人物accentColor视觉感受王奕辰#8B7355经典棕林阿姨#9B8578温暖棕陈若宁#7A8B7A沉稳绿这个颜色不仅用在头像上还用在关系标签和亲密度星标上形成一张卡片一个主色调的效果。5.3 右侧 Column 用 layoutWeight(1).layoutWeight(1).margin({left:16})头像固定 56vp右侧文字用layoutWeight(1)填满剩余宽度。margin({ left: 16 })控制头像和文字之间的间距比维系页的 12-14vp 稍大因为这张卡片整体尺寸更大间距也要相应放大。六、第一行姓名 关系标签Row(){Text(name).fontSize(20).fontWeight(FontWeight.Bold).fontColor(#2C2723)Text(relation).fontSize(12).fontColor(accentColor).padding({left:10,right:10,top:4,bottom:4}).borderRadius(8).backgroundColor(#FAF6EF).margin({left:10})}6.1 关系标签的配色.fontColor(accentColor).backgroundColor(#FAF6EF)文字颜色用accentColor和头像同色背景用#FAF6EF极浅的暖色。这样标签和头像形成色彩呼应同时浅底保证文字可读性。6.2 药丸标签的 padding.padding({left:10,right:10,top:4,bottom:4}).borderRadius(8)上下 4、左右 10 的内边距配合 8vp 圆角形成一个小药丸形状。字号 12 配合这个尺寸视觉上紧凑但不拥挤。七、第二行亲密度星标 上次沟通Row(){ForEach([1,2,3,4,5],(star:number){Text(starintimacy?★:☆).fontSize(13).fontColor(starintimacy?#D4B896:#E0D8CC).margin({right:2})})Text(· 上次沟通${lastContactDays}天前).fontSize(13).fontColor(#B5ADA2).margin({left:8})}.margin({top:6})★★★★☆ · 上次沟通 12 天前7.1 用 ForEach 渲染星标ForEach([1,2,3,4,5],(star:number){Text(starintimacy?★:☆)})5 颗星intimacy是几就亮几颗。ForEach遍历[1,2,3,4,5]每次判断当前星星是否应该亮起。7.2 两色区分亮暗星.fontColor(starintimacy?#D4B896:#E0D8CC)亮星用金色#D4B896暗星用浅灰#E0D8CC。两种颜色饱和度都不高不会抢夺姓名的视觉焦点。7.3 星标和文字之间用 · 分隔Text(· 上次沟通${lastContactDays}天前).margin({left:8})中圆点·作为星标和文字的分隔符比竖线|更柔和。margin({ left: 8 })让分隔符和星标之间有 8vp 的间距。八、分隔线Divider().color(#F0EBE3).margin({top:18,bottom:18})头部信息和备注之间用一条浅色分隔线隔开。#F0EBE3是暖灰色和页面整体色调一致。上下各 18vp 的间距让分隔线两侧都有足够的呼吸空间。九、备注文字Text(note).fontSize(14).lineHeight(22).fontColor(#7A7066).width(100%)14 号字、22 行高行间距约 8vp阅读舒适。#7A7066是中灰色比主文字#2C2723浅比辅助文字#B5ADA2深适合这种重要但不是最醒目的信息。十、标签区Flex 自动换行Flex({wrap:FlexWrap.Wrap}){ForEach(tags,(tag:string){Text(tag).fontSize(12).fontColor(#9A8E82).padding({left:12,right:12,top:6,bottom:6}).borderRadius(14).backgroundColor(#F7F4EE).margin({top:14,right:8})})}.width(100%)10.1 为什么用 Flex 而不是 RowRow不会自动换行。如果标签太多会超出屏幕宽度。Flex({ wrap: FlexWrap.Wrap })会在空间不足时自动换行标签数量从 1 到 N 都能正常展示。10.2 标签的间距控制.margin({top:14,right:8})只设了top和right没有设bottom和left。这样水平方向标签之间靠right: 8分隔。垂直方向换行后靠top: 14分隔。第一行顶部不需要额外间距因为备注文字已经提供了空间。10.3 标签样式.fontSize(12).fontColor(#9A8E82).padding({left:12,right:12,top:6,bottom:6}).borderRadius(14).backgroundColor(#F7F4EE)和关系标签不同这里的标签用灰色#9A8E82 浅底#F7F4EE视觉上更轻。因为一张卡片只有一个关系标签重要但可能有多个特征标签咖啡爱好者、帮过我大忙…特征标签不应该太抢眼。borderRadius(14)配合padding形成圆角药丸和关系标签风格统一。十一、卡片外壳.alignItems(HorizontalAlign.Start).padding(22).borderRadius(22).backgroundColor(#FFFFFF).shadow({radius:14,color:#1A000007,offsetY:4}).margin({bottom:16})11.1 padding 22比维系页的提醒卡片padding 18和久未联系卡片padding 18都大。因为这张卡片信息量更大需要更多内边距让内容不显得拥挤。11.2 borderRadius 22圆角也更大提醒卡片 20、久未联系卡片 18。卡片越大圆角也应该越大否则会显得生硬。11.3 阴影最轻.shadow({radius:14,color:#1A000007,offsetY:4})#1A000007的最后两位07表示约 3% 不透明度是整页最轻的阴影。因为档案页只有一种卡片不需要通过阴影强弱来区分层级——所有卡片地位平等。十二、和维系页的对比两个页面用了相同的外层结构Scroll Column但卡片设计思路完全不同对比项维系页档案页卡片种类3 种提醒、久未联系、统计1 种PersonDetailCard卡片方向提醒横向、久未联系横向全部纵向信息密度提醒卡片高、久未联系低统一中等密度头像尺寸40 / 5056卡片圆角20 / 18 / 2422卡片内边距18 / 18 / 2622分隔线无有头部和备注之间核心区别维系页用不同卡片表达不同优先级档案页用同一卡片表达平等关系。十三、总结这篇我们拆解了档案页面的 UI 布局核心要点单一卡片纵向重复页面结构极简重点全在卡片设计上。头像 layoutWeight固定头像宽度右侧信息弹性填充。accentColor 贯穿卡片头像、关系标签、星标共用一个主色一张卡片一个色调。ForEach 渲染星标5 颗星根据亲密度动态亮灭两色区分。Flex 自动换行标签标签数量不确定时Flex({ wrap: FlexWrap.Wrap })是最稳妥的方案。分隔线划分区域头部信息和备注之间用浅色 Divider 隔开比留白更有结构感。尺寸随卡片放大头像 56、padding 22、borderRadius 22比小卡片都大一圈。