最佳实践-ArkUI框架之组件布局Flex篇
作为一名鸿蒙生态的开发者,首先要入手的就是页面布局,最基础的页面是要有能力画出来并达到给用户带来良好体验的效果,今天要分享的是鸿蒙开发的Flex页面布局。
一、 ArkUI布局概述
1. 布局结构
布局通常为分层结构,一个常见的页面结构如下所示:

为实现上述效果,开发者需要在页面中声明对应的元素。其中,Page表示页面的根节点,Column/Row等元素为系统组件。针对不同的页面结构,ArkUI提供了不同的布局组件来帮助开发者实现对应布局的效果,例如Row用于实现线性布局。
2. 布局元素的组成
这里引用官方API文档里的示例图,明确直观的看出一个元素的布局,具体的组成部分,布局元素组成图

- 组件区域(蓝区方块):实际为width、height设置的大小;
- 组件内容区(黄色方块):组件区域减去组件的border值;
- 组件内容(绿色方块):组件内容本身占用的大小,比如文本内容占用的大小。组件内容和组件内容区不一定匹配,比如设置了固定的width和height,此时组件内容的大小就是设置的width和height减去padding和border值,但文本内容则是通过文本布局引擎测算后得到的大小,可能出现文本真实大小小于设置的组件内容区大小,也就是文本内容无法占满文本组件提供的内容区大小。当组件内容和组件内容区大小不一致时,align属性生效,定义组件内容在组件内容区的对齐方式,如居中对齐。
- 组件布局边界(虚线部分):margin的大小;
3. 如何选择布局
声明式UI提供了以下几种常见布局,开发者可根据实际应用场景选择合适的布局进行页面开发。

当然,接下来的分享主要是Flex布局的应用,在实际开发中,针对实用场景选择最为合适的布局方式也是考验开发者能力的一环。
二、 实战演练:构建“钓鱼圈”首页布局
项目实战场景,直观感受ArkUI布局的强大。
1. 需求分析与设计拆解
“钓鱼圈”首页布局包含:
- 顶部栏:应用标题和用户头像
- 天气卡片:显示当前钓鱼适宜度
- 功能入口:常用功能的网格布局
2. 代码实现与逐层解析
- 总体代码实现:
@Entry
@Component
struct FishingHomePage {
@State currentIndex: number = 0;
build() {
// 根布局:纵向排列
Column() {
// 1. 顶部栏 - 使用Row实现水平布局
Row() {
Text('钓鱼圈')
.fontSize(24)
.fontWeight(FontWeight.Bold)
.layoutWeight(1) // 占据剩余空间,实现左对齐
Image($r('app.media.touxiang'))
.width(40)
.height(40)
.borderRadius(20) // 圆形头像
}
.width('100%')
.padding({ left: 16, right: 16, top: 12, bottom: 12 })
.backgroundColor('#FFFFFF')
// 2. 天气卡片 - 使用Stack实现层叠布局
Stack() {
// 内容区域
Row() {
Column() {
Text('今日适宜钓鱼')
.fontSize(18)
.fontColor('#1F6BF5')
Text('85分')
.fontSize(32)
.margin(12)
.fontColor('#1F6BF5')
.fontWeight(FontWeight.Medium)
}
.layoutWeight(1)
Column() {
Text('气温')
.fontSize(18)
.fontColor('#1F6BF5')
Text('22°C')
.fontSize(32)
.margin(12)
.fontColor('#1F6BF5')
}
.alignItems(HorizontalAlign.Center)
}
.width('100%')
.padding(16)
}
.width('93%')
.height(120)
.linearGradient(
{
angle: 30,
colors: [
['#87CEEB', 0.0],
['#E0F6FF', 0.3],
['#87CEEB', 0.8],
['#87CEEB', 1.0],
],
}
)
.margin({ top: 18, bottom: 18 })
.borderRadius(12)
// 3. 功能flex布局 - 使用Row+Column组合
Column() {
// 第一行功能
Row() {
this.BuildFunctionItem('钓点', $r('app.media.ditu'))
this.BuildFunctionItem('天气', $r('app.media.xunjian'))
this.BuildFunctionItem('潮汐', $r('app.media.heliuguanli'))
this.BuildFunctionItem('记录', $r('app.media.yujing'))
}
.width('100%')
.justifyContent(FlexAlign.SpaceAround)
.margin({ bottom: 30 })
// 第二行功能
Row() {
this.BuildFunctionItem('渔具', $r('app.media.shuiku'))
this.BuildFunctionItem('社区', $r('app.media.duanxin'))
this.BuildFunctionItem('设置', $r('app.media.tongyongpeizhi'))
this.BuildFunctionItem('更多', $r('app.media.xinzeng'))
}
.width('100%')
.justifyContent(FlexAlign.SpaceAround)
}
.layoutWeight(1) // 占据中间所有剩余空间
}
.width('100%')
.height('100%')
.backgroundColor('#F5F6FA')
}
// 构建功能项组件 - 封装重复UI逻辑
@Builder BuildFunctionItem(name: string, icon: Resource) {
Column() {
Image(icon)
.width(60)
.height(60)
.padding(16)
.backgroundColor('#87CEEB')
.borderRadius(12)
.margin({ bottom: 8 })
Text(name)
.fontSize(14)
.fontColor('#333333')
}
.width(70)
.height(70)
.justifyContent(FlexAlign.Center)
.alignItems(HorizontalAlign.Center)
}
}
- 布局效果示意图:
┌─────────────────────────────────┐
│ 钓鱼圈 [头像] │ ← Row水平布局
├─────────────────────────────────┤
│ │
│ 🎣 今日适宜钓鱼 85分 │ ← Stack层叠布局
│ 气温 22°C │
│ │
├─────────────────────────────────┤
│ [钓点] [天气] [潮汐] [记录] │ ← Row + SpaceAround
│ [渔具] [社区] [设置] [更多] │
│ │
──────────────────────────────────
- 实际效果展示:

三、 关键布局技巧
1. 根布局:纵向排列
页面布局首先是拿到UI图,要对图中元素进行切分,每一个块元素需要包含哪些子元素等等,也是考验还原UI的能力,这里很明显的采用了纵向排列布局,将页面划分为纵向排列三个大块:

2. Flex布局的应用
针对于多行多列的数据渲染,项目中采用了flex布局:
// 功能flex布局 - 使用Row+Column组合
Column() {
// 第一行功能
Row() {
this.BuildFunctionItem('钓点', $r('app.media.ditu'))
this.BuildFunctionItem('天气', $r('app.media.xunjian'))
this.BuildFunctionItem('潮汐', $r('app.media.heliuguanli'))
this.BuildFunctionItem('记录', $r('app.media.yujing'))
}
.width('100%')
.justifyContent(FlexAlign.SpaceAround)
.margin({ bottom: 30 })
// 第二行功能
Row() {
this.BuildFunctionItem('渔具', $r('app.media.shuiku'))
this.BuildFunctionItem('社区', $r('app.media.duanxin'))
this.BuildFunctionItem('设置', $r('app.media.tongyongpeizhi'))
this.BuildFunctionItem('更多', $r('app.media.xinzeng'))
}
.width('100%')
.justifyContent(FlexAlign.SpaceAround)
}
.layoutWeight(1) // 占据中间所有剩余空间
3. 精准控制间距
在实际开发中,合理控制间距和图标大小至关重要,从观感上要过关,其次是对重复渲染组件进行封装:
// 构建功能项组件 - 封装重复UI逻辑
@Builder BuildFunctionItem(name: string, icon: Resource) {
Column() {
Image(icon)
.width(60)
.height(60)
.padding(16)
.backgroundColor('#87CEEB')
.borderRadius(12)
.margin({ bottom: 8 })
Text(name)
.fontSize(14)
.fontColor('#333333')
}
.width(70)
.height(70)
.justifyContent(FlexAlign.Center)
.alignItems(HorizontalAlign.Center)
}
}
四、 产品使用体验与总结
1. ArkUI布局优势体验
经过"钓鱼圈"的实际开发,ArkUI布局系统展现出显著优势:
- 声明式语法简洁直观:相比XML布局,代码更紧凑,逻辑更清晰
- 强大的组合能力:通过@Builder等方法,轻松实现组件复用
- 优秀的性能表现:扁平化层级结构,渲染效率高
2. 给开发者的建议
- 布局优先原则:先规划整体结构,再实现细节样式
- 组件化思维:将重复UI抽象为@Builder方法或自定义组件
- 性能意识:避免过度嵌套,合理使用layoutWeight
结语
ArkUI的布局系统保留了传统布局的熟悉感,通过合理的组件选择和属性配置,开发者能够高效构建出美观、流畅的鸿蒙应用界面。
最为印象深刻的点是代码可阅读性很高,ArkUI的布局对于代码洁癖晚期的患者是一味良药,即便是转行过来的小白,也能够快速的入门。
卤煮将进阶ArkUI的动画效果,助力打造更加完善的鸿蒙应用体验。期待和欢迎各位鸿蒙开发者们的加入鸿蒙知识共建交流群!!!!!
更多推荐



所有评论(0)