ArkTS 布局系统概述——从线性到网格,掌握声明式 UI 的骨架艺术
2026/7/27 5:51:57 网站建设 项目流程

文章目录

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

每日一句正能量

“不经思考的行动,到头来只会是无用功。”
没有经过倾听、观察、思考的匆忙行动,往往偏离目标或重复错误。行动之前要先“听见”事实与反馈,否则再努力也是徒劳。
向内建立清晰的边界与自省,再向外选择对的人与事,以倾听和包容为方法,最终达到不费力却深刻的默契与从容。


引言

在 HarmonyOS 应用开发中,UI 界面不仅是视觉的呈现,更是用户与系统交互的桥梁。ArkTS 作为 HarmonyOS 主推的声明式开发语言,其布局系统经历了从传统命令式到现代声明式的范式革命。与早期需要开发者手动计算坐标、逐像素调整位置的命令式布局不同,ArkTS 的布局系统通过组合式 API 让开发者以更接近自然语义的方式描述界面结构,框架自动完成测量、布局与绘制。

本文将系统梳理 ArkTS 布局体系的核心容器与机制,涵盖线性布局、弹性布局、层叠布局、网格布局及响应式适配方案,并结合实际代码示例与性能优化策略,帮助开发者建立完整的布局思维模型。


一、ArkUI 布局系统架构:理解渲染管线

在深入具体布局容器之前,有必要先理解 ArkUI 布局引擎的工作流程。一个组件最终能显示在屏幕的哪个位置,通常会经历三个阶段:

1. 测量阶段(Measure Pass)

父组件向子组件传递可用空间和尺寸约束,子组件根据内容、显式尺寸与约束计算自身大小。例如,当父容器宽度为400vp,子组件设置了width('50%'),则其实际测量宽度为200vp

2. 布局阶段(Layout Pass)

父组件按照自身的布局规则,结合子组件的测量结果,确定每个子组件在容器内的最终坐标位置。这一阶段决定了组件的xy偏移量。

3. 绘制阶段(Draw Pass)

将布局结果渲染到屏幕,生成具体的渲染指令,处理背景、边框、阴影和内容绘制。

ArkUI 3.0 之后引入了增量布局机制,仅重新计算发生变更的部分,而非整棵树重排。同时支持AsyncMeasure异步测量,优化复杂嵌套场景下的布局性能。声明式语法使得开发者只需描述 UI 应该「长什么样」,而无需关心「怎么画」,框架内部通过 Diff 算法直接基于 RENDER 树节点比较差异,实现渲染算法树三合一,界面滑动加载速度较传统方案提升约 45%。


二、线性布局:Column 与 Row

线性布局是 ArkTS 中最基础、最常用的布局方式,通过ColumnRow两个容器组件实现。

Column容器内子组件按照垂直方向依次排列,适用于纵向堆叠的场景,如表单、设置列表、卡片内容等。

Row容器内子组件按照水平方向依次排列,适用于横向排列的场景,如导航栏、工具栏、标签组等。

2.1 核心属性
属性作用Column 取值Row 取值
space主轴方向子组件间距数值数值
justifyContent主轴对齐方式FlexAlignFlexAlign
alignItems交叉轴对齐方式HorizontalAlignVerticalAlign
2.2 代码示例:设置列表项
@Entry@Componentstruct 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')}@BuilderbuildSettingItem(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 核心参数
参数类型说明
directionFlexDirection主轴方向:Row / Column / RowReverse / ColumnReverse
wrapFlexWrap换行方式:NoWrap / Wrap / WrapReverse
justifyContentFlexAlign主轴对齐
alignItemsItemAlign交叉轴对齐
alignContentFlexAlign多行内容对齐(wrap 生效时)
3.2 子组件弹性属性
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 典型应用场景
@Entry@Componentstruct 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 基础用法
@Entry@Componentstruct GridDemo{privateitems: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 跨列与跨行

通过columnStartcolumnEndrowStartrowEnd属性,子组件可以跨越多个网格单元格,实现类似「大图+小图」的复杂布局效果。


六、响应式与自适应布局

HarmonyOS 应用需要同时适配手机、平板、折叠屏、2in1 设备等多种形态,响应式布局是不可或缺的能力。ArkTS 提供了基于断点的栅格系统,以设备水平宽度(vp)作为断点依据。

6.1 栅格断点规则
设备宽度类型列数间隔边距
0 ~ 320vpXS212vp12vp
320 ~ 600vpSM424vp24vp
600 ~ 840vpMD824vp32vp
≥ 840vpLG1224vp48vp
6.2 GridContainer 与 useSizeType
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减少不必要的布局刷新和重绘。

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
欢迎 👍点赞✍评论⭐收藏,欢迎指正

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询