文章目录
-
-
- 每日一句正能量
- 引言
- [一、ArkUI 布局系统架构:理解渲染管线](#一、ArkUI 布局系统架构:理解渲染管线)
- [二、线性布局:Column 与 Row](#二、线性布局:Column 与 Row)
-
- [2.1 核心属性](#2.1 核心属性)
- [2.2 代码示例:设置列表项](#2.2 代码示例:设置列表项)
- [2.3 自适应拉伸:layoutWeight 与 Blank](#2.3 自适应拉伸:layoutWeight 与 Blank)
- 三、弹性布局:Flex
-
- [3.1 核心参数](#3.1 核心参数)
- [3.2 子组件弹性属性](#3.2 子组件弹性属性)
- [3.3 Flex 与 Column/Row 的选型策略](#3.3 Flex 与 Column/Row 的选型策略)
- 四、层叠布局:Stack
-
- [4.1 定位方式](#4.1 定位方式)
- [4.2 典型应用场景](#4.2 典型应用场景)
- 五、网格布局:Grid
-
- [5.1 基础用法](#5.1 基础用法)
- [5.2 跨列与跨行](#5.2 跨列与跨行)
- 六、响应式与自适应布局
-
- [6.1 栅格断点规则](#6.1 栅格断点规则)
- [6.2 GridContainer 与 useSizeType](#6.2 GridContainer 与 useSizeType)
- 七、布局性能优化实践
- 八、总结
-

每日一句正能量
"不经思考的行动,到头来只会是无用功。"
没有经过倾听、观察、思考的匆忙行动,往往偏离目标或重复错误。行动之前要先"听见"事实与反馈,否则再努力也是徒劳。
向内建立清晰的边界与自省,再向外选择对的人与事,以倾听和包容为方法,最终达到不费力却深刻的默契与从容。
引言
在 HarmonyOS 应用开发中,UI 界面不仅是视觉的呈现,更是用户与系统交互的桥梁。ArkTS 作为 HarmonyOS 主推的声明式开发语言,其布局系统经历了从传统命令式到现代声明式的范式革命。与早期需要开发者手动计算坐标、逐像素调整位置的命令式布局不同,ArkTS 的布局系统通过组合式 API 让开发者以更接近自然语义的方式描述界面结构,框架自动完成测量、布局与绘制。
本文将系统梳理 ArkTS 布局体系的核心容器与机制,涵盖线性布局、弹性布局、层叠布局、网格布局及响应式适配方案,并结合实际代码示例与性能优化策略,帮助开发者建立完整的布局思维模型。
一、ArkUI 布局系统架构:理解渲染管线
在深入具体布局容器之前,有必要先理解 ArkUI 布局引擎的工作流程。一个组件最终能显示在屏幕的哪个位置,通常会经历三个阶段:
1. 测量阶段(Measure Pass)
父组件向子组件传递可用空间和尺寸约束,子组件根据内容、显式尺寸与约束计算自身大小。例如,当父容器宽度为 400vp,子组件设置了 width('50%'),则其实际测量宽度为 200vp。
2. 布局阶段(Layout Pass)
父组件按照自身的布局规则,结合子组件的测量结果,确定每个子组件在容器内的最终坐标位置。这一阶段决定了组件的 x、y 偏移量。
3. 绘制阶段(Draw Pass)
将布局结果渲染到屏幕,生成具体的渲染指令,处理背景、边框、阴影和内容绘制。

ArkUI 3.0 之后引入了增量布局机制,仅重新计算发生变更的部分,而非整棵树重排。同时支持 AsyncMeasure 异步测量,优化复杂嵌套场景下的布局性能。声明式语法使得开发者只需描述 UI 应该「长什么样」,而无需关心「怎么画」,框架内部通过 Diff 算法直接基于 RENDER 树节点比较差异,实现渲染算法树三合一,界面滑动加载速度较传统方案提升约 45%。
二、线性布局:Column 与 Row
线性布局是 ArkTS 中最基础、最常用的布局方式,通过 Column 和 Row 两个容器组件实现。
Column 容器内子组件按照垂直方向依次排列,适用于纵向堆叠的场景,如表单、设置列表、卡片内容等。
Row 容器内子组件按照水平方向依次排列,适用于横向排列的场景,如导航栏、工具栏、标签组等。

2.1 核心属性
| 属性 | 作用 | Column 取值 | Row 取值 |
|---|---|---|---|
space |
主轴方向子组件间距 | 数值 | 数值 |
justifyContent |
主轴对齐方式 | FlexAlign |
FlexAlign |
alignItems |
交叉轴对齐方式 | HorizontalAlign |
VerticalAlign |
2.2 代码示例:设置列表项
typescript
@Entry
@Component
struct SettingsPage {
build() {
Column({ space: 12 }) {
// 标题栏
Row() {
Text('设置').fontSize(24).fontWeight(FontWeight.Bold)
Blank() // 自动填充空白
Image($r('app.media.close')).width(24).height(24)
}
.width('100%')
.padding(16)
// 设置项列表
Column({ space: 8 }) {
this.buildSettingItem('Wi-Fi', true)
this.buildSettingItem('蓝牙', false)
this.buildSettingItem('通知', true)
this.buildSettingItem('定位服务', false)
}
.width('100%')
.padding({ left: 16, right: 16 })
}
.width('100%')
.height('100%')
.backgroundColor('#F5F7FA')
}
@Builder
buildSettingItem(label: string, isOn: boolean) {
Row() {
Text(label).fontSize(16).fontColor('#333333')
Blank()
Toggle({ type: ToggleType.Switch, isOn: isOn })
}
.width('100%')
.height(56)
.padding({ left: 16, right: 16 })
.backgroundColor(Color.White)
.borderRadius(12)
}
}
2.3 自适应拉伸:layoutWeight 与 Blank
在线性布局中,layoutWeight 属性用于配置子组件在主轴方向上的尺寸权重。配置该属性后,子组件沿主轴方向的显式尺寸设置将失效,具体尺寸根据权重比例自动计算。Blank 组件则是一个空白填充组件,在容器主轴方向自动填充剩余空间,常用于实现左右对齐的列表项布局。
三、弹性布局:Flex
弹性布局(Flex)的效果类似于线性布局,同样使子元素呈线性排列,但在子元素的排列、对齐和剩余空间分配等方面更加灵活。Flex 是 Web 开发者最熟悉的布局模型之一,ArkTS 完整复刻了 CSS Flexbox 的核心能力。

3.1 核心参数
| 参数 | 类型 | 说明 |
|---|---|---|
direction |
FlexDirection |
主轴方向:Row / Column / RowReverse / ColumnReverse |
wrap |
FlexWrap |
换行方式:NoWrap / Wrap / WrapReverse |
justifyContent |
FlexAlign |
主轴对齐 |
alignItems |
ItemAlign |
交叉轴对齐 |
alignContent |
FlexAlign |
多行内容对齐(wrap 生效时) |
3.2 子组件弹性属性
typescript
Flex({ direction: FlexDirection.Row, wrap: FlexWrap.Wrap }) {
Text('标签 A')
.width(80)
.height(40)
.backgroundColor('#FF9F43')
.flexGrow(1) // 空间充足时按比例扩展
Text('标签 B')
.width(80)
.height(40)
.backgroundColor('#10AC84')
.flexGrow(2) // 分得更多剩余空间
Text('标签 C')
.width(80)
.height(40)
.backgroundColor('#5F27CD')
.flexShrink(0) // 空间不足时不压缩
}
.width('100%')
.padding(12)
3.3 Flex 与 Column/Row 的选型策略

Column/Row 适用于:简单线性排列、页面骨架结构、固定数量的子项、追求代码简洁和极致性能的场景。由于不支持换行,布局计算路径更短,渲染性能更优。
Flex 适用于:需要自动换行(wrap)、多行对齐(alignContent)、主轴方向动态切换、子项数量和大小不确定的流式内容场景。最佳实践是外层用 Column/Row 搭骨架,内层动态区域用 Flex 处理流式内容,两者分层协作。
四、层叠布局:Stack
层叠布局(Stack)用于在屏幕上预留一块区域来显示组件中的元素,提供元素可以重叠的布局能力。容器中的子元素依次入栈,后一个子元素覆盖前一个子元素,类似于 Photoshop 中的图层叠加。

4.1 定位方式
Stack 容器支持两种定位方式:
- 默认定位:子组件按添加顺序依次叠加,无偏移时中心对齐
- 绝对定位 :通过
position({ x, y })或offset({ x, y })精确控制位置
4.2 典型应用场景
typescript
@Entry
@Component
struct StackDemo {
build() {
Stack({ alignContent: Alignment.Center }) {
// 底层:背景图
Image($r('app.media.cover'))
.width('100%')
.height(200)
.objectFit(ImageFit.Cover)
// 中层:半透明遮罩
Column()
.width('100%')
.height(200)
.backgroundColor('rgba(0,0,0,0.4)')
// 顶层:文字内容
Column() {
Text('鸿蒙生态赋能')
.fontSize(24)
.fontColor(Color.White)
.fontWeight(FontWeight.Bold)
Text('第五期技术实战')
.fontSize(14)
.fontColor('#DDDDDD')
.margin({ top: 8 })
}
}
.width('100%')
.height(200)
}
}
层叠布局的典型应用场景包括:广告弹窗、卡片层叠效果、图片水印叠加、视频播放控制层叠加等。通过 zIndex 属性还可以手动控制层级顺序,数值越大越靠上。
五、网格布局:Grid
网格布局(Grid)是一种二维布局系统,支持将容器划分为若干行和列,子组件按照指定的行列位置进行放置。相比线性布局的一维排列,网格布局能更高效地实现复杂的卡片矩阵、相册网格、仪表盘等界面。

5.1 基础用法
typescript
@Entry
@Component
struct GridDemo {
private items: string[] = ['相册', '相机', '日历', '时钟', '天气', '地图']
build() {
Grid() {
ForEach(this.items, (item: string, index: number) => {
GridItem() {
Column() {
Image($r(`app.media.icon_${index}`))
.width(48)
.height(48)
Text(item)
.fontSize(14)
.margin({ top: 8 })
}
.width('100%')
.height('100%')
.justifyContent(FlexAlign.Center)
}
.backgroundColor('#F5F7FA')
.borderRadius(16)
})
}
.columnsTemplate('1fr 1fr 1fr') // 三列等宽
.rowsTemplate('1fr 1fr') // 两行等高
.columnsGap(12)
.rowsGap(12)
.padding(16)
.width('100%')
.height(400)
}
}
5.2 跨列与跨行
通过 columnStart、columnEnd、rowStart、rowEnd 属性,子组件可以跨越多个网格单元格,实现类似「大图+小图」的复杂布局效果。
六、响应式与自适应布局
HarmonyOS 应用需要同时适配手机、平板、折叠屏、2in1 设备等多种形态,响应式布局是不可或缺的能力。ArkTS 提供了基于断点的栅格系统,以设备水平宽度(vp)作为断点依据。

6.1 栅格断点规则
| 设备宽度 | 类型 | 列数 | 间隔 | 边距 |
|---|---|---|---|---|
| 0 ~ 320vp | XS | 2 | 12vp | 12vp |
| 320 ~ 600vp | SM | 4 | 24vp | 24vp |
| 600 ~ 840vp | MD | 8 | 24vp | 32vp |
| ≥ 840vp | LG | 12 | 24vp | 48vp |
6.2 GridContainer 与 useSizeType
typescript
GridContainer() {
Row() {
Text('自适应卡片')
.useSizeType({
xs: { span: 2, offset: 0 }, // 手机:占满2列
sm: { span: 2, offset: 0 }, // 大屏手机:占2列
md: { span: 4, offset: 0 }, // 平板:占4列
lg: { span: 6, offset: 0 }, // 2in1:占6列
})
}
}
通过 useSizeType 属性,开发者可以为同一组件在不同断点下指定不同的列跨度(span)和偏移量(offset),实现真正的「一次开发,多端部署」。
七、布局性能优化实践
布局性能直接影响应用的流畅度和用户体验。以下是 ArkTS 布局优化的核心策略:
1. 减少布局层级嵌套
每增加一层嵌套,就会多一轮 Measure 和 Layout 计算。尽量扁平化组件树,能用单层 Flex 解决的不用嵌套 Column+Row。
2. 优先使用 Column/Row 而非 Flex
Column/Row 只处理一维线性排列,布局计算路径更短,渲染性能优于 Flex。仅在需要换行、多行对齐等 Flex 特有能力时才使用 Flex。
3. 避免在循环中创建复杂布局
对于长列表,使用 LazyForEach 替代 ForEach,配合 cachedCount 预加载缓存项,避免一次性渲染全部子组件。
4. 合理使用固定尺寸
当组件内容尺寸确定时,优先使用固定数值(如 width(200))而非百分比或自适应计算,可减少测量阶段的递归开销。
5. 利用 freezeWhenInactive 冻结不可见组件
对于不可见或离屏组件,启用 freezeWhenInactive 减少不必要的布局刷新和重绘。
typescript
List() {
LazyForEach(this.dataSource, (item: Item) => {
ListItem() {
ItemComponent({ item: item })
}
.freezeWhenInactive(true)
})
}
.cachedCount(3) // 预加载3个缓存项
八、总结
ArkTS 的布局系统以声明式语法为核心,通过 Column/Row、Flex、Stack、Grid 等丰富的容器组件,覆盖了从简单线性排列到复杂二维网格的全场景需求。理解各容器的设计哲学与能力边界,是写出高效、优雅、可维护 UI 代码的前提。
在实际开发中,建议遵循以下原则:
- 骨架层用 Column/Row:页面整体结构采用线性布局搭建,保证性能与可读性
- 动态区用 Flex:标签流、按钮组等动态内容区域使用 Flex 的换行与弹性能力
- 叠加区用 Stack:弹窗、遮罩、水印等层叠场景使用 Stack 实现
- 矩阵区用 Grid:卡片矩阵、相册、仪表盘等二维排列使用 Grid 实现
- 跨端用 GridContainer:响应式场景下结合断点与栅格系统实现多端自适应
掌握这套布局体系,你就掌握了 ArkTS 声明式 UI 的骨架艺术,为构建高性能、高颜值的 HarmonyOS 应用打下坚实基础。
转载自:https://blog.csdn.net/u014727709/article/details/163198448
欢迎 👍点赞✍评论⭐收藏,欢迎指正