文章目录前言一、主轴与交叉轴1.1 概念理解1.2 justifyContent 所有值1.3 本项目中的 justifyContent 用法二、alignItems交叉轴对齐2.1 Column 中的 HorizontalAlign2.2 Row 中的 VerticalAlign三、layoutWeight按比例分配空间3.1 什么是 layoutWeight四、space vs padding vs margin4.1 三者的区别4.2 本项目中的间距设计规范五、综合实战仿原生设置页面总结前言Row横向排列和Column纵向排列是 ArkUI 中最基础也最重要的布局容器几乎每个页面都离不开它们。但很多初学者写出来的布局歪七扭八究其原因是没有真正理解主轴/交叉轴、justifyContent、alignItems这几个核心概念。本篇从原理出发结合本项目真实 UI带你彻底掌握 ArkUI 弹性布局体系。一、主轴与交叉轴1.1 概念理解Column纵向容器 主轴 垂直方向 ↕ 交叉轴 水平方向 ↔ Row横向容器 主轴 水平方向 ↔ 交叉轴 垂直方向 ↕justifyContent控制子组件在主轴上的分布方式alignItems控制子组件在交叉轴上的对齐方式1.2 justifyContent 所有值EntryComponentstruct JustifyDemo{privateitems:string[][A,B,C];BuilderrowDemo(label:string,align:FlexAlign){Column({space:4}){Text(label).fontSize(11).fontColor(#999999)Row({space:0}){ForEach(this.items,(item:string){Text(item).width(40).height(40).backgroundColor(#1A6FF5).fontColor(#FFFFFF).fontSize(16).textAlign(TextAlign.Center)})}.width(100%).height(50).backgroundColor(#F0F4FF).borderRadius(8).justifyContent(align)// ← 切换这里}}build(){Scroll(){Column({space:12}){this.rowDemo(Start靠左,FlexAlign.Start)this.rowDemo(Center居中,FlexAlign.Center)this.rowDemo(End靠右,FlexAlign.End)this.rowDemo(SpaceBetween两端对齐,FlexAlign.SpaceBetween)this.rowDemo(SpaceAround环绕间距,FlexAlign.SpaceAround)this.rowDemo(SpaceEvenly均匀间距,FlexAlign.SpaceEvenly)}.padding(16)}.width(100%).height(100%)}}FlexAlign 值效果Start子组件靠主轴起始端排列Center子组件在主轴居中End子组件靠主轴末端排列SpaceBetween首尾无间距中间均匀分配SpaceAround每个子组件两侧相等间距SpaceEvenly所有间距含首尾完全相等1.3 本项目中的 justifyContent 用法GasStationPage.ets中的stationInfoCardRow(){Column({space:Constants.SPACE_6}){Text(gasStation.name)// 站名Text(gasStation.addr)// 地址}.alignItems(HorizontalAlign.Start);// 列内左对齐if(this.isCalculated){Text(${距离}km)// 距离条件渲染}}.width(Constants.PERCENT_70).justifyContent(FlexAlign.SpaceBetween)// ← 站名靠左距离靠右SpaceBetween让站名和距离分别顶向两端——这是一个非常经典的左文字右数值布局模式。二、alignItems交叉轴对齐2.1 Column 中的 HorizontalAlignEntryComponentstruct AlignItemsDemo{build(){Row({space:16}){// 水平对齐Start默认Column({space:8}){Text(标题).fontSize(16).fontWeight(FontWeight.Bold)Text(副标题较长文本).fontSize(13).fontColor(#999999)Text(短文本).fontSize(13).fontColor(#999999)}.alignItems(HorizontalAlign.Start)// 子组件左对齐.padding(12).backgroundColor(#E8F0FE).borderRadius(8)// 水平对齐CenterColumn({space:8}){Text(标题).fontSize(16).fontWeight(FontWeight.Bold)Text(副标题较长文本).fontSize(13).fontColor(#999999)Text(短文本).fontSize(13).fontColor(#999999)}.alignItems(HorizontalAlign.Center)// 子组件居中.padding(12).backgroundColor(#E8F5E9).borderRadius(8)}.padding(16)}}2.2 Row 中的 VerticalAlignRow({space:12}){// 大图标Image($r(app.media.startIcon)).width(48).height(48)// 文字高度不同Column({space:4}){Text(中国石化望京加油站).fontSize(16).fontWeight(FontWeight.Bold)Text(北京市海淀区).fontSize(13).fontColor(#999999)}.alignItems(HorizontalAlign.Start)}.alignItems(VerticalAlign.Center)// ← 图标和文字垂直居中对齐.width(100%).padding(16)三、layoutWeight按比例分配空间3.1 什么是 layoutWeightlayoutWeight是 ArkUI 中实现弹性分配剩余空间的属性类似 CSS Flexbox 中的flex-grow。EntryComponentstruct LayoutWeightDemo{build(){Column({space:16}){// 示例11:2 比例Row(){Text(1份).layoutWeight(1).height(40).backgroundColor(#FF4D4F).textAlign(TextAlign.Center).fontColor(#FFFFFF)Text(2份).layoutWeight(2).height(40).backgroundColor(#1A6FF5).textAlign(TextAlign.Center).fontColor(#FFFFFF)}.width(100%)// 示例2固定宽度 弹性填充剩余Row({space:8}){Image($r(app.media.startIcon)).width(48)// 固定48px.height(48)Column({space:4}){Text(加油站名称)Text(详细地址)}.alignItems(HorizontalAlign.Start).layoutWeight(1)// 占据剩余所有空间Text(1.2km).width(60)// 固定60px.textAlign(TextAlign.End).fontColor(#1A6FF5)}.width(100%).padding(16).backgroundColor(#FFFFFF).borderRadius(12)}.padding(16)}}本项目源码中layoutWeight的使用// MainPage.etsRow(){Image($r(app.media.image1)).width(Constants.GAS_STATION_IMAGE_WIDTH).height(Constants.GAS_STATION_IMAGE_HEIGHT);Row(){Text($r(app.string.gas_station))Image($r(app.media.chevron_right))}.layoutWeight(Constants.ONE)// 文字行占据 Row 剩余所有空间.justifyContent(FlexAlign.SpaceBetween);// 文字靠左箭头靠右}四、space vs padding vs margin4.1 三者的区别EntryComponentstruct SpacingDemo{build(){Column({space:12}){// space: Column 内部子组件之间的间距// padding组件内部的内边距Text(内边距 padding).padding({left:16,right:16,top:8,bottom:8}).backgroundColor(#E8F0FE).borderRadius(8)// margin组件外部的外边距Text(外边距 margin).margin({left:32})// 向右缩进.padding(8).backgroundColor(#E8F5E9).borderRadius(8)// 两者同时使用Text(padding margin 组合).padding(16).margin({top:8,bottom:8}).backgroundColor(#FFF8E1).borderRadius(8)}.padding(16)// 容器本身的内边距保护内容不贴边.width(100%)}}4.2 本项目中的间距设计规范从Constants.ets可以看出本项目有统一的间距规范常量名值使用场景SPACE_66紧凑元素间距如名称和地址SPACE_88标准小间距SPACE_1212标准中间距SPACE_1616标准大间距Row 内主要元素PADDING_LEFT_1212左内边距PADDING_LEFT_1616大左内边距统一使用常量管理间距值让全局修改布局参数变得极为简单。五、综合实战仿原生设置页面EntryComponentstruct SettingsPage{StatelocationEnabled:booleantrue;StatenotifyEnabled:booleanfalse;Statetheme:string跟随系统;privatethemeOptions:string[][浅色,深色,跟随系统];toggleTheme():void{constidx:numberthis.themeOptions.indexOf(this.theme);this.themethis.themeOptions[(idx1)%this.themeOptions.length];}BuildersettingItem(icon:string,title:string,subtitle:string,trailing:()void){Row(){Row({space:12}){// 左图标Text(icon).fontSize(22).width(40).height(40).textAlign(TextAlign.Center).backgroundColor(#F0F4FF).borderRadius(10)// 中标题副标题Column({space:2}){Text(title).fontSize(16).fontWeight(FontWeight.Medium).fontColor(#1A1A1A)Text(subtitle).fontSize(13).fontColor(#999999)}.alignItems(HorizontalAlign.Start).layoutWeight(1)// 占据剩余空间}.width(100%)}.padding({left:16,right:16,top:14,bottom:14}).width(100%).backgroundColor(#FFFFFF)}build(){Column({space:0}){// 标题栏Row(){Text(设置).fontSize(20).fontWeight(FontWeight.Bold)}.padding({left:20,right:20,top:56,bottom:16}).width(100%).backgroundColor(#F5F7FA)// 设置列表Column({space:1}){// 分组1位置服务Text(位置服务).fontSize(13).fontColor(#999999).padding({left:20,top:16,bottom:8}).alignSelf(ItemAlign.Start)this.settingItem(,位置权限,允许应用访问您的位置,(){Toggle({type:ToggleType.Switch,isOn:this.locationEnabled}).onChange(v{this.locationEnabledv;}).selectedColor(#1A6FF5)})Divider().strokeWidth(0.5).color(#F0F0F0).padding({left:68})this.settingItem(️,地图显示,显示附近加油站,(){Image($r(app.media.startIcon)).width(16).height(16).opacity(0.5)})// 分组2通知设置Text(通知).fontSize(13).fontColor(#999999).padding({left:20,top:16,bottom:8}).alignSelf(ItemAlign.Start)this.settingItem(,推送通知,接收优惠和提醒信息,(){Toggle({type:ToggleType.Switch,isOn:this.notifyEnabled}).onChange(v{this.notifyEnabledv;}).selectedColor(#52C41A)})// 分组3外观Text(外观).fontSize(13).fontColor(#999999).padding({left:20,top:16,bottom:8}).alignSelf(ItemAlign.Start)Row(){Row({space:12}){Text().fontSize(22).width(40).height(40).textAlign(TextAlign.Center).backgroundColor(#F0F4FF).borderRadius(10)Column({space:2}){Text(主题模式).fontSize(16).fontWeight(FontWeight.Medium).fontColor(#1A1A1A)Text(this.theme).fontSize(13).fontColor(#999999)}.alignItems(HorizontalAlign.Start).layoutWeight(1)Text(this.theme).fontSize(14).fontColor(#999999)}.width(100%)}.padding({left:16,right:16,top:14,bottom:14}).width(100%).backgroundColor(#FFFFFF).onClick((){this.toggleTheme()})}.backgroundColor(#F5F7FA)}.width(100%).height(100%).backgroundColor(#F5F7FA)}}总结Row 和 Column 是 ArkUI 布局的骨架掌握主轴/交叉轴的概念是理解所有布局行为的关键。justifyContent控制主轴分布alignItems控制交叉轴对齐layoutWeight实现弹性空间分配——三者配合可以实现任何你在主流 App 中见到的布局效果。space、padding、margin的合理运用则决定了界面的视觉层次和呼吸感。
HarmonyOS ArkUI 弹性布局:Row 与 Column 深度解析
发布时间:2026/6/8 14:57:23
文章目录前言一、主轴与交叉轴1.1 概念理解1.2 justifyContent 所有值1.3 本项目中的 justifyContent 用法二、alignItems交叉轴对齐2.1 Column 中的 HorizontalAlign2.2 Row 中的 VerticalAlign三、layoutWeight按比例分配空间3.1 什么是 layoutWeight四、space vs padding vs margin4.1 三者的区别4.2 本项目中的间距设计规范五、综合实战仿原生设置页面总结前言Row横向排列和Column纵向排列是 ArkUI 中最基础也最重要的布局容器几乎每个页面都离不开它们。但很多初学者写出来的布局歪七扭八究其原因是没有真正理解主轴/交叉轴、justifyContent、alignItems这几个核心概念。本篇从原理出发结合本项目真实 UI带你彻底掌握 ArkUI 弹性布局体系。一、主轴与交叉轴1.1 概念理解Column纵向容器 主轴 垂直方向 ↕ 交叉轴 水平方向 ↔ Row横向容器 主轴 水平方向 ↔ 交叉轴 垂直方向 ↕justifyContent控制子组件在主轴上的分布方式alignItems控制子组件在交叉轴上的对齐方式1.2 justifyContent 所有值EntryComponentstruct JustifyDemo{privateitems:string[][A,B,C];BuilderrowDemo(label:string,align:FlexAlign){Column({space:4}){Text(label).fontSize(11).fontColor(#999999)Row({space:0}){ForEach(this.items,(item:string){Text(item).width(40).height(40).backgroundColor(#1A6FF5).fontColor(#FFFFFF).fontSize(16).textAlign(TextAlign.Center)})}.width(100%).height(50).backgroundColor(#F0F4FF).borderRadius(8).justifyContent(align)// ← 切换这里}}build(){Scroll(){Column({space:12}){this.rowDemo(Start靠左,FlexAlign.Start)this.rowDemo(Center居中,FlexAlign.Center)this.rowDemo(End靠右,FlexAlign.End)this.rowDemo(SpaceBetween两端对齐,FlexAlign.SpaceBetween)this.rowDemo(SpaceAround环绕间距,FlexAlign.SpaceAround)this.rowDemo(SpaceEvenly均匀间距,FlexAlign.SpaceEvenly)}.padding(16)}.width(100%).height(100%)}}FlexAlign 值效果Start子组件靠主轴起始端排列Center子组件在主轴居中End子组件靠主轴末端排列SpaceBetween首尾无间距中间均匀分配SpaceAround每个子组件两侧相等间距SpaceEvenly所有间距含首尾完全相等1.3 本项目中的 justifyContent 用法GasStationPage.ets中的stationInfoCardRow(){Column({space:Constants.SPACE_6}){Text(gasStation.name)// 站名Text(gasStation.addr)// 地址}.alignItems(HorizontalAlign.Start);// 列内左对齐if(this.isCalculated){Text(${距离}km)// 距离条件渲染}}.width(Constants.PERCENT_70).justifyContent(FlexAlign.SpaceBetween)// ← 站名靠左距离靠右SpaceBetween让站名和距离分别顶向两端——这是一个非常经典的左文字右数值布局模式。二、alignItems交叉轴对齐2.1 Column 中的 HorizontalAlignEntryComponentstruct AlignItemsDemo{build(){Row({space:16}){// 水平对齐Start默认Column({space:8}){Text(标题).fontSize(16).fontWeight(FontWeight.Bold)Text(副标题较长文本).fontSize(13).fontColor(#999999)Text(短文本).fontSize(13).fontColor(#999999)}.alignItems(HorizontalAlign.Start)// 子组件左对齐.padding(12).backgroundColor(#E8F0FE).borderRadius(8)// 水平对齐CenterColumn({space:8}){Text(标题).fontSize(16).fontWeight(FontWeight.Bold)Text(副标题较长文本).fontSize(13).fontColor(#999999)Text(短文本).fontSize(13).fontColor(#999999)}.alignItems(HorizontalAlign.Center)// 子组件居中.padding(12).backgroundColor(#E8F5E9).borderRadius(8)}.padding(16)}}2.2 Row 中的 VerticalAlignRow({space:12}){// 大图标Image($r(app.media.startIcon)).width(48).height(48)// 文字高度不同Column({space:4}){Text(中国石化望京加油站).fontSize(16).fontWeight(FontWeight.Bold)Text(北京市海淀区).fontSize(13).fontColor(#999999)}.alignItems(HorizontalAlign.Start)}.alignItems(VerticalAlign.Center)// ← 图标和文字垂直居中对齐.width(100%).padding(16)三、layoutWeight按比例分配空间3.1 什么是 layoutWeightlayoutWeight是 ArkUI 中实现弹性分配剩余空间的属性类似 CSS Flexbox 中的flex-grow。EntryComponentstruct LayoutWeightDemo{build(){Column({space:16}){// 示例11:2 比例Row(){Text(1份).layoutWeight(1).height(40).backgroundColor(#FF4D4F).textAlign(TextAlign.Center).fontColor(#FFFFFF)Text(2份).layoutWeight(2).height(40).backgroundColor(#1A6FF5).textAlign(TextAlign.Center).fontColor(#FFFFFF)}.width(100%)// 示例2固定宽度 弹性填充剩余Row({space:8}){Image($r(app.media.startIcon)).width(48)// 固定48px.height(48)Column({space:4}){Text(加油站名称)Text(详细地址)}.alignItems(HorizontalAlign.Start).layoutWeight(1)// 占据剩余所有空间Text(1.2km).width(60)// 固定60px.textAlign(TextAlign.End).fontColor(#1A6FF5)}.width(100%).padding(16).backgroundColor(#FFFFFF).borderRadius(12)}.padding(16)}}本项目源码中layoutWeight的使用// MainPage.etsRow(){Image($r(app.media.image1)).width(Constants.GAS_STATION_IMAGE_WIDTH).height(Constants.GAS_STATION_IMAGE_HEIGHT);Row(){Text($r(app.string.gas_station))Image($r(app.media.chevron_right))}.layoutWeight(Constants.ONE)// 文字行占据 Row 剩余所有空间.justifyContent(FlexAlign.SpaceBetween);// 文字靠左箭头靠右}四、space vs padding vs margin4.1 三者的区别EntryComponentstruct SpacingDemo{build(){Column({space:12}){// space: Column 内部子组件之间的间距// padding组件内部的内边距Text(内边距 padding).padding({left:16,right:16,top:8,bottom:8}).backgroundColor(#E8F0FE).borderRadius(8)// margin组件外部的外边距Text(外边距 margin).margin({left:32})// 向右缩进.padding(8).backgroundColor(#E8F5E9).borderRadius(8)// 两者同时使用Text(padding margin 组合).padding(16).margin({top:8,bottom:8}).backgroundColor(#FFF8E1).borderRadius(8)}.padding(16)// 容器本身的内边距保护内容不贴边.width(100%)}}4.2 本项目中的间距设计规范从Constants.ets可以看出本项目有统一的间距规范常量名值使用场景SPACE_66紧凑元素间距如名称和地址SPACE_88标准小间距SPACE_1212标准中间距SPACE_1616标准大间距Row 内主要元素PADDING_LEFT_1212左内边距PADDING_LEFT_1616大左内边距统一使用常量管理间距值让全局修改布局参数变得极为简单。五、综合实战仿原生设置页面EntryComponentstruct SettingsPage{StatelocationEnabled:booleantrue;StatenotifyEnabled:booleanfalse;Statetheme:string跟随系统;privatethemeOptions:string[][浅色,深色,跟随系统];toggleTheme():void{constidx:numberthis.themeOptions.indexOf(this.theme);this.themethis.themeOptions[(idx1)%this.themeOptions.length];}BuildersettingItem(icon:string,title:string,subtitle:string,trailing:()void){Row(){Row({space:12}){// 左图标Text(icon).fontSize(22).width(40).height(40).textAlign(TextAlign.Center).backgroundColor(#F0F4FF).borderRadius(10)// 中标题副标题Column({space:2}){Text(title).fontSize(16).fontWeight(FontWeight.Medium).fontColor(#1A1A1A)Text(subtitle).fontSize(13).fontColor(#999999)}.alignItems(HorizontalAlign.Start).layoutWeight(1)// 占据剩余空间}.width(100%)}.padding({left:16,right:16,top:14,bottom:14}).width(100%).backgroundColor(#FFFFFF)}build(){Column({space:0}){// 标题栏Row(){Text(设置).fontSize(20).fontWeight(FontWeight.Bold)}.padding({left:20,right:20,top:56,bottom:16}).width(100%).backgroundColor(#F5F7FA)// 设置列表Column({space:1}){// 分组1位置服务Text(位置服务).fontSize(13).fontColor(#999999).padding({left:20,top:16,bottom:8}).alignSelf(ItemAlign.Start)this.settingItem(,位置权限,允许应用访问您的位置,(){Toggle({type:ToggleType.Switch,isOn:this.locationEnabled}).onChange(v{this.locationEnabledv;}).selectedColor(#1A6FF5)})Divider().strokeWidth(0.5).color(#F0F0F0).padding({left:68})this.settingItem(️,地图显示,显示附近加油站,(){Image($r(app.media.startIcon)).width(16).height(16).opacity(0.5)})// 分组2通知设置Text(通知).fontSize(13).fontColor(#999999).padding({left:20,top:16,bottom:8}).alignSelf(ItemAlign.Start)this.settingItem(,推送通知,接收优惠和提醒信息,(){Toggle({type:ToggleType.Switch,isOn:this.notifyEnabled}).onChange(v{this.notifyEnabledv;}).selectedColor(#52C41A)})// 分组3外观Text(外观).fontSize(13).fontColor(#999999).padding({left:20,top:16,bottom:8}).alignSelf(ItemAlign.Start)Row(){Row({space:12}){Text().fontSize(22).width(40).height(40).textAlign(TextAlign.Center).backgroundColor(#F0F4FF).borderRadius(10)Column({space:2}){Text(主题模式).fontSize(16).fontWeight(FontWeight.Medium).fontColor(#1A1A1A)Text(this.theme).fontSize(13).fontColor(#999999)}.alignItems(HorizontalAlign.Start).layoutWeight(1)Text(this.theme).fontSize(14).fontColor(#999999)}.width(100%)}.padding({left:16,right:16,top:14,bottom:14}).width(100%).backgroundColor(#FFFFFF).onClick((){this.toggleTheme()})}.backgroundColor(#F5F7FA)}.width(100%).height(100%).backgroundColor(#F5F7FA)}}总结Row 和 Column 是 ArkUI 布局的骨架掌握主轴/交叉轴的概念是理解所有布局行为的关键。justifyContent控制主轴分布alignItems控制交叉轴对齐layoutWeight实现弹性空间分配——三者配合可以实现任何你在主流 App 中见到的布局效果。space、padding、margin的合理运用则决定了界面的视觉层次和呼吸感。