公司动态
【HarmonyOS 6】卡片布局实战:打造精美的信息展示界面
前言卡片Card是移动应用中最常用的模块。它将相关信息组织在一个独立的容器中通过各种各样的视觉元素营造出层次分明、易于浏览的界面效果。在本文中我们将通过一个实际案例展示如何在HarmonyOS应用中实现各种类型的卡片布局。本应用中的卡片类型在我们的健康管理应用中使用了多种类型的卡片健康评分卡片展示综合评分和各项分数数据统计卡片展示饮水、运动、打卡等数据快捷入口卡片提供快速导航功能建议列表卡片展示健康建议让我们逐一学习这些卡片的实现方法。一、健康评分卡片这是应用首页最重要的卡片展示用户的综合健康评分。1.1 卡片结构1.2 完整代码// 健康评分卡片Column(){Row(){// 左侧评分圆环Stack(){// 背景圆环Progress({value:100,total:100,type:ProgressType.Ring}).width(this.getRingSize()).height(this.getRingSize()).color($r(app.color.primary_surface)).style({strokeWidth:this.getRingStrokeWidth()})// 进度圆环Progress({value:this.healthScore.totalScore,total:100,type:ProgressType.Ring}).width(this.getRingSize()).height(this.getRingSize()).color($r(app.color.primary_color)).style({strokeWidth:this.getRingStrokeWidth()})// 中心文字Column(){Row(){Text(this.healthScore.totalScore.toString()).fontSize(36).fontWeight(FontWeight.Bold).fontColor($r(app.color.primary_dark))Text(/100).fontSize(12).fontColor($r(app.color.text_secondary)).margin({bottom:4})}.alignItems(VerticalAlign.Bottom)Text(今日总评).fontSize(12).fontColor($r(app.color.text_secondary))}}// 右侧分项进度Column(){// 打卡进度Row(){Text(打卡).fontSize(12).fontColor($r(app.color.text_secondary)).width(32)Progress({value:this.healthScore.checkInScore,total:100,type:ProgressType.Linear}).height(8).color($r(app.color.primary_color)).backgroundColor($r(app.color.input_background)).layoutWeight(1).borderRadius(4)Text(${Math.round(this.healthScore.checkInScore*0.25)}/25).fontSize(12).fontColor($r(app.color.text_primary)).width(36).textAlign(TextAlign.End)}.width(100%).margin({top:10})// 饮水进度类似结构// 运动进度类似结构// 睡眠进度类似结构}.layoutWeight(1).padding({left:24})}.width(100%)// 底部说明文字Text(满分100 打卡25 饮水25 运动25 睡眠25).fontSize(12).fontColor($r(app.color.text_primary)).width(100%).margin({top:12})}.width(100%).padding(24).margin({left:16,right:16}).backgroundColor($r(app.color.card_background)).borderRadius(20)1.3 布局的要点左右分栏布局左侧固定宽度圆环大小右侧使用layoutWeight(1)占据剩余空间圆环叠加使用Stack实现多层叠加底层是背景圆环浅色上层是进度圆环主题色最上层是中心文字进度条布局标签固定宽度32进度条使用layoutWeight(1)自适应数值固定宽度36并右对齐1.4 响应式设计// 圆环大小根据屏幕调整privategetRingSize():number{returngetValueByBreakpoint(this.currentBreakpoint,newBreakpointValuenumber(100,120,140));}// 圆环线宽根据屏幕调整privategetRingStrokeWidth():number{returngetValueByBreakpoint(this.currentBreakpoint,newBreakpointValuenumber(10,12,14));}// 卡片内边距根据屏幕调整privategetCardPadding():number{returngetValueByBreakpoint(this.currentBreakpoint,newBreakpointValuenumber(20,24,28));}二、数据统计卡片这类卡片用于展示单一数据指标简洁明了。2.1 卡片结构2.2 完整代码Row(){// 饮水卡片Column(){Text(饮水).fontSize(14).fontColor($r(app.color.text_secondary))Row(){Text(this.waterCurrent.toString()).fontSize(28).fontWeight(FontWeight.Bold).fontColor($r(app.color.water_blue))Text(ml).fontSize(12).fontColor($r(app.color.text_secondary)).margin({left:4,bottom:4})}.alignItems(VerticalAlign.Bottom).margin({top:8})}.width(31%).padding({top:20,bottom:20,left:16,right:16}).backgroundColor($r(app.color.water_surface)).borderRadius(16).alignItems(HorizontalAlign.Start)// 运动卡片Column(){Text(运动).fontSize(14).fontColor($r(app.color.text_secondary))Row(){Text(this.exerciseMinutes.toString()).fontSize(28).fontWeight(FontWeight.Bold).fontColor($r(app.color.accent_color))Text(分钟).fontSize(12).fontColor($r(app.color.text_secondary)).margin({left:4,bottom:4})}.alignItems(VerticalAlign.Bottom).margin({top:8})}.width(31%).padding({top:20,bottom:20,left:16,right:16}).backgroundColor($r(app.color.food_surface)).borderRadius(16).alignItems(HorizontalAlign.Start)// 打卡卡片Column(){Text(打卡).fontSize(14).fontColor($r(app.color.text_secondary))Row(){Text(this.checkInCount.toString()).fontSize(28).fontWeight(FontWeight.Bold).fontColor($r(app.color.primary_color))Text(/${this.checkInTotal}).fontSize(12).fontColor($r(app.color.text_secondary)).margin({left:4,bottom:4})}.alignItems(VerticalAlign.Bottom).margin({top:8})}.width(31%).padding({top:20,bottom:20,left:16,right:16}).backgroundColor($r(app.color.primary_surface)).borderRadius(16).alignItems(HorizontalAlign.Start)}.width(100%).justifyContent(FlexAlign.SpaceBetween).padding({left:16,right:16,top:16})2.3 布局的要点三等分布局每个卡片宽度 31%留出间距使用justifyContent(FlexAlign.SpaceBetween)均匀分布自动计算卡片间距数值与单位对齐使用Row包裹数值和单位数值大字号、粗体、彩色单位小字号、灰色使用alignItems(VerticalAlign.Bottom)底部对齐颜色区分每个卡片使用不同的背景色数值颜色与背景色相呼应形成视觉上的分类效果2.4 响应式宽度// 响应式宽度配置.width(getValueByBreakpoint(this.currentBreakpoint,newBreakpointValuestring(31%,31%,32%)))在大屏上可以稍微增加宽度减少间距。三、快捷入口卡片快捷入口卡片提供快速导航功能通常使用按钮样式。3.1 卡片结构3.2 完整代码Column(){Text(快捷入口).fontSize(16).fontWeight(FontWeight.Medium).fontColor($r(app.color.text_primary)).width(100%)Row(){this.QuickBtn(打卡,$r(app.color.primary_surface),$r(app.color.primary_color),()this.switchToTab(1))this.QuickBtn(饮水,$r(app.color.water_blue_light),$r(app.color.water_blue),()this.switchToTab(2))this.QuickBtn(运动,$r(app.color.exercise_surface),$r(app.color.accent_color),()this.switchToTab(3))this.QuickBtn(睡眠,$r(app.color.sleep_surface),$r(app.color.sleep_purple),()this.switchToTab(4))}.width(100%).justifyContent(FlexAlign.SpaceBetween).margin({top:16})}.width(100%).padding({left:16,right:16,top:16})BuilderQuickBtn(label:string,bgColor:ResourceColor,textColor:ResourceColor,onClick:()void){Column(){Text(label).fontSize(14).fontColor(textColor)}.width(23%).height(50).justifyContent(FlexAlign.Center).backgroundColor(bgColor).borderRadius(12).onClick(onClick)}3.3 布局的要点四等分布局每个按钮宽度 23%留出间距使用justifyContent(FlexAlign.SpaceBetween)均匀分布按钮样式固定高度50圆角12背景色与文字色搭配居中对齐Builder 封装将重复的按钮结构封装为 Builder通过参数传递标签、颜色、点击事件提高代码复用性3.4 响应式高度privategetQuickBtnHeight():number{returngetValueByBreakpoint(this.currentBreakpoint,newBreakpointValuenumber(50,56,64));}四、建议列表卡片建议列表卡片用于展示多条文本信息。4.1 卡片结构4.2 完整代码Column(){Text(今日建议).fontSize(16).fontWeight(FontWeight.Medium).fontColor($r(app.color.text_primary)).width(100%)Column(){ForEach(this.suggestions,(suggestion:string,index:number){Row(){Column().width(6).height(6).backgroundColor($r(app.color.primary_dark)).borderRadius(3)Text(suggestion).fontSize(14).fontColor($r(app.color.text_primary)).margin({left:12}).layoutWeight(1)}.width(100%).padding({top:12,bottom:12})})}.width(100%).padding(20).margin({top:16}).backgroundColor($r(app.color.card_background)).borderRadius(16)}.width(100%).padding({left:16,right:16,top:16,bottom:16})4.3 布局的要点列表项结构使用ForEach遍历数据每项包含圆点和文字圆点固定宽度6文字使用layoutWeight(1)自适应圆点设计使用Column创建圆点宽高相等6x6圆角为宽度的一半3使用主题色间距设计列表项上下内边距12圆点与文字间距12整体卡片内边距20总结通过本文的学习我们了解了如何在 HarmonyOS 应用中实现各种类型的卡片布局并且我们结合实际案例讲解了四种卡片的具体实现。