Skip to content

常用布局容器

ArkUI 提供 6 种核心布局容器,掌握它们的使用场景和嵌套规则。


1. 6 种布局容器总览

容器布局方向适用场景关键特性
Row水平排列横排菜单、标签栏flex-wrap, justify-content
Column垂直排列列表、表单、页面布局flex-wrap, justify-content
Stack层叠排列图片叠加、悬浮按钮z-index、锚点定位
Flex弹性排列自适应布局、响应式flex-grow/shrink/basis
Grid网格排列商品列表、相册行列定义、自动填充
RelativeContainer相对定位复杂布局、锚点定位锚点、相对定位

2. Row — 水平布局

2.1 基本用法

typescript
Row() {
    Text('Item 1')
        .padding(10)
    Text('Item 2')
        .padding(10)
    Text('Item 3')
        .padding(10)
}
.width('100%')
.justifyContent(FlexAlign.Start)  // 对齐方式
.gap(10)                            // 间距

2.2 常用属性

属性说明
justifyContent水平方向对齐(Start/Center/End/SpaceAround/SpaceBetween)
alignItems交叉轴对齐(Start/Center/End/Baseline)
gap子元素间距
width/height容器尺寸
wrap是否换行(Wrap/NoWrap)

3. Column — 垂直布局

3.1 基本用法

typescript
Column() {
    Text('标题')
        .fontSize(24)
        .fontWeight(FontWeight.Bold)
    Divider()
    Text('内容')
        .fontSize(16)
    Button('按钮')
        .width('100%')
}
.width('100%')
.height('100%')
.justifyContent(FlexAlign.Start)
.gap(10)

3.2 弹性布局子元素

typescript
Column() {
    Text('固定内容')
        .height(100)
    // 空白填充,把内容推到最底部
    Blank()
    Text('底部内容')
        .height(50)
}
.height('100%')

💡 Blank 组件:在 Row 或 Column 中自动填充剩余空间,常用于"左边文字-右边图标"或"顶部内容-底部固定"的布局。


4. Stack — 层叠布局

4.1 基本用法

typescript
Stack() {
    // 底层
    Image('background.jpg')
        .width('100%')
        .height('200vp')

    // 上层
    Text('覆盖文字')
        .fontSize(24)
        .fontColor(Color.White)
        .position({ x: 20, y: 20 })
}
.width('100%')
.height('200vp')

4.2 Stack 的锚点定位

typescript
Stack() {
    // 子元素可以通过 position 或 alignContent 定位
    Image('icon')
        .position({ x: '50%', y: '50%' })  // 中心定位

    Text('Badge')
        .position({ x: '80%', y: '10%' })  // 右上角
}
.width('200vp')
.height('200vp')

4.3 适用场景

  • 图片 + 文字覆盖
  • 悬浮按钮(FAB)
  • 头像 + 在线状态标记
  • 视频封面 + 播放按钮

5. Flex — 弹性布局

5.1 基本用法

typescript
Flex() {
    // flexGrow: 1 → 占据剩余空间的权重
    Text('Item 1')
        .flexGrow(1)

    Text('Item 2')
        .flexGrow(1)

    // 固定宽度
    Text('固定')
        .width(100)
}
.width('100%')
.flexWrap(FlexWrap.Wrap)    // 可换行
.mainAxisAlign(FlexAlign.Center)  // 主轴对齐
.crossAxisAlign(CrossAxisAlign.Center)  // 交叉轴对齐

5.2 flexGrow / flexShrink / flexBasis

属性说明
flexGrow分配剩余空间的比例
flexShrink空间不足时缩小比例
flexBasis初始尺寸
typescript
Flex() {
    Text('A')
        .flexGrow(2)       // 占 2 份
        .width(100)
    Text('B')
        .flexGrow(1)       // 占 1 份
        .width(100)
}
.width('100%')

5.3 适用场景

  • 自适应宽度的卡片列表
  • 响应式导航栏
  • 内容分配不均的布局

6. Grid — 网格布局

6.1 基本用法

typescript
Grid() {
    GridItem() {
        Text('1')
    }
    GridItem() {
        Text('2')
    }
    GridItem() {
        Text('3')
    }
    GridItem() {
        Text('4')
    }
}
.columnsTemplate('1fr 1fr 1fr')  // 3 列等宽
.rowsTemplate('100vp 100vp')      // 2 行
.gap(8)
.width('100%')

6.2 网格模板

typescript
// 1fr = 1 fraction(等分剩余空间)
.columnsTemplate('1fr 2fr 1fr')    // 4:2:1 的比例
.rowsTemplate('auto 1fr auto')     // 第一行自动高度,中间撑满,最后一行自动

6.3 适用场景

  • 商品/照片列表
  • 仪表盘
  • 九宫格菜单

7. RelativeContainer — 相对布局 ⭐

7.1 解决的核心痛点

嵌套过深 → 减少布局层级 → 提升渲染性能

传统方式(嵌套深):
Column → Row → Stack → Image
                    → Text
                    → Button
                    → Row → Text

相对布局(扁平):
RelativeContainer → Image(锚点A)
               → Text(锚点A)
               → Button(锚点B)

7.2 基本用法

typescript
// 定义锚点
@Entry
@Component
struct Index {
    build() {
        RelativeContainer() {
            // 定义锚点
            Rect()
                .id('anchor1')
                .width(0)
                .height(0)
                .position({ x: 50, y: 50 })

            // 图片:锚点 anchor1 的右下角
            Image('icon.png')
                .alignRules({
                    top: { anchor: 'anchor1', align: VerticalAlign.Top },
                    left: { anchor: 'anchor1', align: HorizontalAlign.Start }
                })
                .width(100)
                .height(100)

            // 文字:相对于图片的位置
            Text('描述')
                .alignRules({
                    top: { anchor: 'anchor1', align: VerticalAlign.Top },
                    right: { anchor: 'image', align: HorizontalAlign.End },
                    bottom: { anchor: 'image', align: VerticalAlign.Bottom }
                })
        }
        .width('100%')
        .height('100%')
    }
}

7.3 对齐方式

锚点对齐说明
HorizontalAlign.Start左对齐
HorizontalAlign.End右对齐
HorizontalAlign.Center居中
VerticalAlign.Top顶对齐
VerticalAlign.Bottom底对齐
VerticalAlign.Middle垂直居中

7.4 适用场景

  • 复杂商品卡片
  • 相册照片叠加
  • 地图标注

8. 布局容器嵌套规则

8.1 推荐嵌套方式

typescript
// 页面级:Column 或 Row 为主框架
Column() {
    // 头部
    Row() { ... }

    // 内容
    Stack() {
        Image('banner')
        Text('标题')
    }

    // 列表
    List() { ... }

    // 底部
    Row() { ... }
}

8.2 避免嵌套过深

typescript
// ❌ 嵌套超过 4 层,性能下降
Column() → Row() → Stack() → Column() → Text()

// ✅ 提取为子组件
@Component
struct Header { ... }    // Row
@Component
struct Banner { ... }    // Stack
build() {
    Column() {
        Header()
        Banner()
        List()
    }
}

9. 面试高频考点

Q1: 6 种布局容器分别是什么?各自适用什么场景?

回答

  • Row:水平排列,导航栏/标签
  • Column:垂直排列,页面主框架/列表
  • Stack:层叠排列,图片覆盖/悬浮元素
  • Flex:弹性排列,自适应/响应式
  • Grid:网格排列,商品列表/相册
  • RelativeContainer:相对定位,复杂布局(解决嵌套过深问题)

Q2: RelativeContainer 解决了什么痛点?

回答:解决复杂布局中嵌套层级过深的问题。通过锚点(Anchor)定位,减少布局次数,提升渲染性能。

Q3: Blank 组件的作用?

回答:在 Row/Column 中自动填充剩余空间,常用于将两端组件推到边缘(如"左边文字-右边图标")或把内容推到屏幕底部。


🐱 小猫提示:6 种容器记住口诀:横排 Row,竖排 Column,层叠 Stack,弹性 Flex,网格 Grid,相对 RelativeContainer。面试直接报出这 6 个名字就够。