当前位置: 首页 > news >正文

HarmonyOS ArkUI Column 与 Row 布局:justifyContent、alignItems 与 layoutWeight

系列:鸿蒙 HarmonyOS 6.1 新特性实战 · 第 46 篇

Column 和 Row 是 ArkUI 中最基础的两种线性布局容器,分别沿垂直和水平方向排列子组件。掌握justifyContentalignItemslayoutWeight这三个核心属性,能解决日常开发中绝大多数的布局需求。本篇通过可运行的完整示例,系统讲解每个属性的含义与适用场景。

运行效果

初始状态(Column 默认 Start 对齐):

切换到 SpaceBetween 模式后,子元素均匀分布在两端之间:

Column 的主轴对齐:justifyContent

Column 的主轴是垂直方向justifyContent控制子组件沿垂直方向的分布方式。ArkUI 提供了六种FlexAlign值:

枚举值效果
FlexAlign.Start子组件紧靠顶部(默认)
FlexAlign.Center子组件整体居中
FlexAlign.End子组件紧靠底部
FlexAlign.SpaceBetween首尾紧贴边缘,其余均分间距
FlexAlign.SpaceAround每个子组件两侧各有相等的边距
FlexAlign.SpaceEvenly所有间距(含首尾)完全相等
// Column justifyContent 示例 Column() { Text('A') .width('80%').height(40) .backgroundColor('#e8f0ff') .textAlign(TextAlign.Center) Text('B') .width('80%').height(40) .backgroundColor('#b3d1ff') .textAlign(TextAlign.Center) Text('C') .width('80%').height(40) .backgroundColor('#6699ff') .fontColor('#fff') .textAlign(TextAlign.Center) } .width('100%').height(200) .justifyContent(FlexAlign.SpaceBetween) // 改成 SpaceAround / SpaceEvenly / Center / Start / End 观察差异

SpaceBetween:A 顶部对齐,C 底部对齐,B 居中。SpaceAround:三个元素各自两侧间距相等,因此首尾有半个间距。SpaceEvenly:所有间距(含首尾)完全一致,视觉上最均匀。

Row 的交叉轴对齐:alignItems

Row 的主轴是水平方向,交叉轴是垂直方向alignItems控制子组件在垂直方向的对齐。当子组件高度不同时,效果尤为明显:

// Row alignItems 示例:子组件高度各不相同 Row({ space: 8 }) { Text('Top') .height(40) .backgroundColor('#e8f0ff') .padding(8) Text('Center\n两行') .height(80) .backgroundColor('#b3d1ff') .padding(8) Text('Bottom') .height(60) .backgroundColor('#6699ff') .fontColor('#fff') .padding(8) } .width('100%') .alignItems(VerticalAlign.Center) // Top / Center / Bottom

VerticalAlign.Top使所有子组件顶部对齐;Center使它们垂直居中;Bottom使底部对齐。同理,Column 的alignItems接受HorizontalAlign.Start/Center/End,控制子组件在水平方向的对齐。

layoutWeight:按比例分配剩余空间

当需要让子组件按比例瓜分父容器的剩余空间时,使用layoutWeight。设置了该属性后,组件自身的width(在 Row 中)或height(在 Column 中)会被忽略,由权重值决定最终尺寸。

// 1:2:1 比例分配横向空间 Row() { Text('1') .layoutWeight(1) .height(44) .backgroundColor('#e8f0ff') .textAlign(TextAlign.Center) Text('2') .layoutWeight(2) .height(44) .backgroundColor('#0066ff') .fontColor('#fff') .textAlign(TextAlign.Center) Text('1') .layoutWeight(1) .height(44) .backgroundColor('#e8f0ff') .textAlign(TextAlign.Center) } .width('100%')

三个 Text 的权重比为 1:2:1,中间元素占父容器宽度的一半,两端各占四分之一。若父容器宽度为 360vp,则分别为 90vp、180vp、90vp。

space 参数 vs padding/margin

Column 和 Row 都支持构造参数{ space: number },用于在相邻子组件之间插入统一间距,首个子组件前和最后一个子组件后不产生额外间距:

// space 参数:仅在子组件之间添加间距 Column({ space: 12 }) { Text('第一行').width('80%').height(40).backgroundColor('#e8f0ff').textAlign(TextAlign.Center) Text('第二行').width('80%').height(40).backgroundColor('#b3d1ff').textAlign(TextAlign.Center) Text('第三行').width('80%').height(40).backgroundColor('#6699ff').fontColor('#fff').textAlign(TextAlign.Center) } .width('100%').padding({ top: 16, bottom: 16, left: 16, right: 16 }) // padding 控制容器内边距,space 控制子组件间距,两者各司其职

spacejustifyContent: SpaceEvenly的区别:space是固定像素值,首尾无间距;SpaceEvenly是自适应均分,首尾也有相等间距。

完整代码

import { FlexAlign, VerticalAlign, HorizontalAlign } from '@ohos.arkui.common' @Entry @Component struct ColumnRowDemo { @State alignMode: FlexAlign = FlexAlign.Start private modes: FlexAlign[] = [ FlexAlign.Start, FlexAlign.Center, FlexAlign.End, FlexAlign.SpaceBetween, FlexAlign.SpaceAround, FlexAlign.SpaceEvenly ] private modeNames: string[] = [ 'Start', 'Center', 'End', 'SpaceBetween', 'SpaceAround', 'SpaceEvenly' ] @State modeIndex: number = 0 build() { Column({ space: 24 }) { // 标题 Text('Column justifyContent 演示') .fontSize(16).fontWeight(FontWeight.Bold).fontColor('#1a1a1a') // justifyContent 演示区 Column() { Text('A') .width('80%').height(40) .backgroundColor('#e8f0ff').textAlign(TextAlign.Center) Text('B') .width('80%').height(40) .backgroundColor('#b3d1ff').textAlign(TextAlign.Center) Text('C') .width('80%').height(40) .backgroundColor('#6699ff').fontColor('#fff').textAlign(TextAlign.Center) } .width('100%').height(200) .backgroundColor('#f8f9ff').borderRadius(8) .justifyContent(this.alignMode) // 当前模式标签 Text('当前模式:' + this.modeNames[this.modeIndex]) .fontSize(13).fontColor('#666') // 切换按钮 Button('切换 justifyContent') .width('60%').height(40) .onClick(() => { this.modeIndex = (this.modeIndex + 1) % this.modes.length this.alignMode = this.modes[this.modeIndex] }) Divider().strokeWidth(1).color('#e0e0e0') // Row alignItems 演示 Text('Row alignItems 演示(高度各异)') .fontSize(16).fontWeight(FontWeight.Bold).fontColor('#1a1a1a') Row({ space: 8 }) { Text('Top') .height(40).backgroundColor('#e8f0ff').padding(8) Text('Center\n两行') .height(80).backgroundColor('#b3d1ff').padding(8) Text('Bottom') .height(60).backgroundColor('#6699ff').fontColor('#fff').padding(8) } .width('100%').alignItems(VerticalAlign.Center) .backgroundColor('#f8f9ff').borderRadius(8).padding(8) Divider().strokeWidth(1).color('#e0e0e0') // layoutWeight 演示 Text('layoutWeight 1:2:1 比例分配') .fontSize(16).fontWeight(FontWeight.Bold).fontColor('#1a1a1a') Row() { Text('1') .layoutWeight(1).height(44) .backgroundColor('#e8f0ff').textAlign(TextAlign.Center) Text('2') .layoutWeight(2).height(44) .backgroundColor('#0066ff').fontColor('#fff').textAlign(TextAlign.Center) Text('1') .layoutWeight(1).height(44) .backgroundColor('#e8f0ff').textAlign(TextAlign.Center) } .width('100%') } .width('100%').padding(16) .backgroundColor('#ffffff') } }

API 速查

属性/方法说明
Column({ space: number })设置子组件之间的垂直间距(不含首尾)
Row({ space: number })设置子组件之间的水平间距(不含首尾)
.justifyContent(FlexAlign)控制主轴方向的子组件分布方式
.alignItems(VerticalAlign)Row 中控制交叉轴(垂直)对齐
.alignItems(HorizontalAlign)Column 中控制交叉轴(水平)对齐
FlexAlign.Start主轴起始方向靠齐
FlexAlign.SpaceBetween首尾贴边,其余均分间距
FlexAlign.SpaceAround每个元素两侧各有等量外边距
FlexAlign.SpaceEvenly所有间距(含首尾)完全相等
.layoutWeight(number)按权重比例分配主轴剩余空间,忽略自身 width/height

小结

  • justifyContent控制主轴方向的分布(Column=垂直,Row=水平),六种 FlexAlign 值各有适用场景
  • alignItems控制交叉轴方向的对齐(Column=水平,Row=垂直),子组件高度不同时效果最明显
  • space参数在子组件之间插入固定间距,首尾不受影响,与justifyContent可以同时使用
  • layoutWeight忽略组件在主轴方向的自身尺寸,按权重分配剩余空间,实现弹性比例布局
  • SpaceBetween 首尾贴边;SpaceAround 两侧各有半间距;SpaceEvenly 所有间距完全一致
  • 简单线性排列优先用 Column/Row,复杂换行或双轴控制场景再考虑 Flex

上一篇:Toast、AlertDialog 与 CustomDialog 弹窗全解 | 下一篇:Flex 弹性布局完全指南

http://www.cnnetsun.cn/news/3551593.html

相关文章:

  • C++实现USB数据监控:从协议解析到HID键盘捕获实战
  • 特征工程十年演进:从手工规则到自监督学习
  • AI产品落地实战:从技术原型到商业成功的核心挑战与解决方案
  • 苹果Siri升级Gemini大模型:移动AI新纪元
  • Spring Boot中RedisAutoConfiguration的自动配置原理与实践
  • Bonzomatic跨平台部署指南:从源码编译到性能调优
  • 我发现别人博客的字要比我多
  • verilog HDLBits刷题[Karnaugh Map to Circuit]“Exams/m2014 q3”---Kamaugh map
  • AI内容检测与优化工具:核心技术解析与应用实践
  • 深入理解C++输入缓冲区:从cin与getline混用陷阱到健壮输入处理
  • 全球主流汽车品牌车标识别与鉴赏指南
  • VC++图像处理实战:从GDI到算法实现,掌握底层图像处理原理
  • OPIK开源框架:AI提示词自动优化技术解析
  • 中小企业AI问答代运营服务选型与实施指南
  • 2022数博会隐私计算与数据要素流通技术解析
  • DagsHub镜像机制:实现Git+DVC+MLflow跨环境协同
  • C++性能优化实战:从核心原理到高效编程与工具链应用
  • TradingAgents-CN终极指南:3分钟打造你的AI金融交易大脑
  • 5分钟上手:用163MusicLyrics轻松解决你的音乐歌词难题
  • 电气设施安装工程合同双语实践指南
  • 最大熵原理:如何为贝叶斯先验选择最无偏的概率分布
  • C++实现差分进化算法:原理详解与工程实践指南
  • Spring 事务失效的 8 种场景与源码级排查
  • 影刀RPA 百度统计自动采集:网站流量数据日报化
  • PyBind11实战避坑指南:C++与Python混合编程的常见陷阱与解决方案
  • DIY音响与监听音箱的性价比对比
  • 解决Windows系统libcef.dll缺失错误的完整指南
  • 3D NAND闪存技术:从原理到千层堆叠实现
  • 实施工程师面试核心要点与高频题解析
  • 好用的UPVC门窗加工机器哪个评价最好