前言布局最容易翻车的不是复杂嵌套而是「对齐」——主菜单整体居中、规则面板左对齐、按钮居中放、三栏 HUD 横排……这些视觉背后是justifyContentalignItems双轴对齐的组合。新手常把这两个属性搞反在Column里用justifyContent(Center)想居中子元素结果子元素上下挤在一起用alignItems想控制垂直排列结果水平对齐乱了。本篇以「猫猫大作战」主菜单整体居中、规则面板左对齐为锚点把Column与Row的主轴/交叉轴双轴对齐体系讲透。读完本篇你将能独立写出整体居中布局、左对齐阅读型布局、三栏均分布局、首尾贴边中间均分布局四种对齐套路。提示本系列不讲 ArkTS 基础语法与环境搭建假设你已跟完第 1–6 篇。一、场景拆解主菜单两种对齐并存打开entry/src/main/ets/pages/Index.ets的MainMenuView// 来源entry/src/main/ets/pages/Index.ets MainMenuView() Column() { // ... 标题、按钮、规则面板 } .width(100%).height(100%) .linearGradient({ /* ... */ }) .alignItems(HorizontalAlign.Center) // 子元素水平居中 // 规则面板嵌套 Column Column() { /* ... 5 行规则 ... */ } .width(80%).padding(16) .backgroundColor(rgba(255,255,255,0.7)).borderRadius(12) .alignItems(HorizontalAlign.Start) // 规则左对齐主菜单整体HorizontalAlign.Center标题、按钮居中显眼但规则面板内部HorizontalAlign.Start规则左对齐扫读。同一个界面两种对齐并存——这是实战常态。二、主轴与交叉轴的概念参考 线性布局 (Row/Column) 官方指南。容器主轴交叉轴alignItems控justifyContent控Column垂直 ↓水平 ↔水平对齐垂直排列Row水平 ↔垂直 ↓垂直对齐水平排列记忆口诀alignItems永远控交叉轴与排列方向垂直justifyContent永远控主轴排列方向。2.1 Column 的两个属性Column() { Text(第一项).width(50%).backgroundColor(#E74C3C) Text(第二项).width(50%).backgroundColor(#3498DB) Text(第三项).width(50%).backgroundColor(#2ECC71) } .width(100%).height(100%) .alignItems(HorizontalAlign.Center) // 水平居中交叉轴 .justifyContent(FlexAlign.Center) // 垂直居中主轴alignItems(HorizontalAlign.Center)三个Text各 50% 宽在容器水平方向居中——左右留白均分。justifyContent(FlexAlign.Center)三个Text整体在容器垂直方向居中——上下留白均分。2.2 Row 的两个属性Row() { Text(左).height(40).backgroundColor(#E74C3C) Text(中).height(40).backgroundColor(#3498DB) Text(右).height(40).backgroundColor(#2ECC71) } .width(100%).height(100%) .alignItems(VerticalAlign.Center) // 垂直居中交叉轴 .justifyContent(FlexAlign.Center) // 水平居中主轴alignItems(VerticalAlign.Center)三个Text各 40 高在容器垂直方向居中——上下留白均分。justifyContent(FlexAlign.Center)三个Text整体在容器水平方向居中——左右留白均分。三、alignItems 交叉轴对齐枚举3.1 HorizontalAlignColumn 用HorizontalAlign.Start // 左对齐 HorizontalAlign.Center // 居中 HorizontalAlign.End // 右对齐3.2 VerticalAlignRow 用VerticalAlign.Top // 顶对齐 VerticalAlign.Center // 居中 VerticalAlign.Bottom // 对齐关键易错Column用HorizontalAlignRow用VerticalAlign——用错枚举类型编译报错。四、justifyContent 主轴排列枚举FlexAlign六值Column与Row通用模式视觉3 子元素说明Start首贴顶依次排默认Center居中上下空对称整体居中End尾贴底依次排整体沉底SpaceBetween首尾贴边中间均分中间空 总空/(子数-1)SpaceAround每元素上下空对称首尾空是中间空的一半SpaceEvenly含首尾全均分首尾空 中间空4.1 主菜单整体居中 vs 顶部起排// 写法 1顶部 Blank 自然排本项目偏上 Column() { Blank().height(15%) Text().fontSize(72) Text(猫猫大作战).fontSize(36) // ... } .height(100%).alignItems(HorizontalAlign.Center) // 写法 2justifyContent 居中正中 Column() { Text().fontSize(72) Text(猫猫大作战).fontSize(36) // ... } .height(100%).alignItems(HorizontalAlign.Center) .justifyContent(FlexAlign.Center) // 写法 3SpaceBetween 首尾贴边 Column() { Text(顶部标题).fontSize(20) Text(中部内容).fontSize(16) Text(底部按钮).fontSize(14) } .height(100%).justifyContent(FlexAlign.SpaceBetween)主菜单选写法 1游戏主菜单要偏上而非正中因为「开始游戏」按钮要落在拇指易触区屏下半部。正中会让按钮过于居中反而不易触。4.2 三栏 HUD 横排 SpaceBetween游戏页底部 HUD 三栏得分/预告/控制用RowSpaceBetweenRow() { Text(得分: ${this.score}).fontSize(16).fontColor(#2C3E50) Column() { Text(下一个).fontSize(12).fontColor(#95A5A6) Text(this.nextCatEmoji).fontSize(24) } Row() { Button(暂停).width(80).height(40) Button(重开).width(80).height(40).margin({ left: 8 }) } } .width(100%).padding({ left: 16, right: 16 }) .justifyContent(FlexAlign.SpaceBetween) .alignItems(VerticalAlign.Center)SpaceBetween让三栏首尾贴边、中间均分——经典 HUD 布局。五、双轴对齐组合实战5.1 整体居中Center CenterColumn() { Text(加载中...).fontSize(16) LoadingProgress().width(48).color(#2ECC71) } .width(100%).height(100%) .alignItems(HorizontalAlign.Center) .justifyContent(FlexAlign.Center)加载页、空状态页、错误页常用——内容和 Loading 整体居中。5.2 顶部起排 水平居中Start CenterColumn() { Text(设置).fontSize(20).fontWeight(FontWeight.Bold).margin({ bottom: 16 }) Text(通知).fontSize(16).margin({ bottom: 12 }) Text(隐私).fontSize(16).margin({ bottom: 12 }) Text(关于).fontSize(16) } .width(100%).height(100%) .alignItems(HorizontalAlign.Center) // 水平居中 .justifyContent(FlexAlign.Start) // 顶部起排默认可省略设置页、列表页常用——顶部起排每项水平居中。5.3 左对齐 顶部起排Start StartColumn() { Text(游戏规则).fontSize(14).fontWeight(FontWeight.Bold).margin({ bottom: 8 }) Text(• 点击列投放猫咪).fontSize(13).margin({ bottom: 4 }) Text(• 相邻同级合并).fontSize(13) } .width(80%).padding(16) .backgroundColor(rgba(255,255,255,0.7)).borderRadius(12) .alignItems(HorizontalAlign.Start) // 左对齐 .justifyContent(FlexAlign.Start) // 顶部起排默认可省略规则面板、说明文档常用——阅读型内容左对齐顶部起排。5.4 底部贴边 水平居中End CenterColumn() { Button(下一步).width(70%).height(56).fontSize(18).backgroundColor(#2ECC71) } .width(100%).height(100%) .alignItems(HorizontalAlign.Center) .justifyContent(FlexAlign.End) // 底部贴边 .padding({ bottom: 32 })引导页、向导页常用——按钮沉底水平居中。六、嵌套容器的对齐协同主菜单是「外层 Column 居中 内层规则 Column 左对齐」的嵌套Column() { Text().fontSize(72) Text(猫猫大作战).fontSize(36) Button(开始游戏).width(70%).height(56) // 嵌套规则面板内部左对齐 Column() { Text(游戏规则).fontSize(14).fontWeight(FontWeight.Bold).margin({ bottom: 8 }) Text(• 点击列投放猫咪).fontSize(13).margin({ bottom: 4 }) // ... } .width(80%).padding(16) .backgroundColor(rgba(255,255,255,0.7)).borderRadius(12) .alignItems(HorizontalAlign.Start) // 内层左对齐 } .width(100%).height(100%) .alignItems(HorizontalAlign.Center) // 外层居中关键点外层Center标题、按钮、规则面板整体水平居中。内层Start规则面板内部 5 行规则左对齐。内层 width 80%规则面板不顶满居中后两侧留白。嵌套对齐原则外层控板块位置内层控板块内部对齐。一个板块的位置由父容器alignItems决定板块内部对齐由自己alignItems决定。七、常见错误示范7.1 在 Column 里用 justifyContent 想水平居中// ❌ 错justifyContent 控垂直排列不控水平 Column() { Text(内容).width(50%) } .justifyContent(FlexAlign.Center) // 这是垂直居中不是水平 // ✅ 对水平居中用 alignItems Column() { Text(内容).width(50%) } .alignItems(HorizontalAlign.Center)7.2 在 Row 里用 alignItems(HorizontalAlign)// ❌ 错Row 的 alignItems 接 VerticalAlign不接 HorizontalAlign Row() { Text(内容).height(40) } .alignItems(HorizontalAlign.Center) // 类型错误编译报错 // ✅ 对Row 垂直居中用 VerticalAlign.Center Row() { Text(内容).height(40) } .alignItems(VerticalAlign.Center)7.3 justifyContent 忘了设 height// ❌ 错没设 heightjustifyContent 无空间可排 Column() { Text(顶部) Text(底部) } .justifyContent(FlexAlign.Center) // height 未设内容撑开就是高度无空可居中 // ✅ 对设 height 让容器有空间 Column() { Text(顶部) Text(底部) } .height(100%) // 有高度居中才生效 .justifyContent(FlexAlign.Center)八、完整代码主菜单双轴对齐Builder MainMenuView() { Column() { Blank().height(15%) Text().fontSize(72).margin({ bottom: 8 }) Text(猫猫大作战).fontSize(36).fontWeight(FontWeight.Bold).fontColor(#2C3E50).margin({ bottom: 8 }) Text(合并进化 · 策略消除).fontSize(16).fontColor(#95A5A6).margin({ bottom: 48 }) Button(开始游戏) .width(70%).height(56).fontSize(20).fontWeight(FontWeight.Bold) .fontColor(#FFFFFF).backgroundColor(#2ECC71).borderRadius(28) .shadow({ radius: 8, color: rgba(46,204,113,0.4), offsetY: 4 }) .margin({ bottom: 24 }) .onClick(() { this.startGame(); }) Column() { Text(游戏规则).fontSize(14).fontWeight(FontWeight.Bold).fontColor(#2C3E50).margin({ bottom: 8 }) Text(• 点击列投放猫咪).fontSize(13).fontColor(#7F8C8D).margin({ bottom: 4 }) Text(• 相邻同级猫咪自动合并升级).fontSize(13).fontColor(#7F8C8D).margin({ bottom: 4 }) Text(• 连续合并触发连击加分).fontSize(13).fontColor(#7F8C8D).margin({ bottom: 4 }) Text(• 猫咪堆到顶部则游戏结束).fontSize(13).fontColor(#7F8C8D) } .width(80%).padding(16) .backgroundColor(rgba(255,255,255,0.7)).borderRadius(12) .alignItems(HorizontalAlign.Start) // 内层左对齐 } .width(100%).height(100%) .linearGradient({ direction: GradientDirection.Bottom, colors: [[#E8F4F8, 0.0], [#D6EEF5, 0.5], [#C9E8F2, 1.0]] }) .alignItems(HorizontalAlign.Center) // 外层居中 }九、调试技巧对齐怎么量加临时 border给容器和子元素都加.border({ width: 1, color: Color.Red })看清边界和留白。justifyContent验 height居中/沉底不生效多半是忘设height。alignItems验 width水平居中不生效子元素width是否顶满顶满就无空可居中。嵌套看两层外层alignItems控板块位置内层alignItems控板块内部——分开调。十、性能与最佳实践justifyContent比Blank高效整体居中用justifyContent(Center)比手动加Blank性能优。alignItems默认Start不写就是左/顶对齐明确写出来更可读。嵌套对齐分两层外层控板块位置内层控板块内部别试图一层Column全搞定。SpaceBetween首尾贴边HUD 三栏用SpaceBetween但别忘padding让首尾不真贴屏边。总结本篇我们从主菜单双轴对齐切入掌握Column/Row的主轴/交叉轴体系并把justifyContent六值与alignItems三值的组合套路讲透。核心要点alignItems控交叉轴justifyContent控主轴Column 用 HorizontalAlignRow 用 VerticalAlign嵌套分两层。下一篇我们将继续主菜单拆解最高分徽章的Row横向布局。如果这篇文章对你有帮助欢迎点赞、收藏⭐、关注你的支持是我持续创作的动力相关资源「猫猫大作战」项目源码本仓库entry/src/main/ets/pages/Index.ets线性布局 (Row/Column) 官方指南Column API 参考Row API 参考FlexAlign 枚举开源鸿蒙跨平台社区HarmonyOS 开发者官方文档首页系列索引本仓库articles/INDEX.md