系列文章:鸿蒙NEXT开发实战系列 -- 第12篇 适合人群:鸿蒙开发初学者 开发环境:DevEco Studio 5.0.5+ | HarmonyOS NEXT (API 14) 阅读时长:约25分钟

引言:6种布局方式总览

布局是UI开发的基石,决定了界面元素的排列方式和空间分配。鸿蒙ArkUI提供了6种核心布局容器,覆盖从简单到复杂的各种界面需求:

布局容器

排列方式

典型场景

Column

垂直线性排列

表单、列表项、垂直导航

Row

水平线性排列

工具栏、标签页、水平卡片

Stack

层叠重叠排列

轮播图、角标、悬浮按钮

RelativeContainer

相对定位排列

复杂表单、不规则布局

Flex

弹性盒子排列

响应式布局、自适应排列

Grid

网格排列

图片墙、仪表盘、矩阵布局

掌握这6种布局,你就能实现任何复杂的界面设计。下面逐一详解。


1. 线性布局 Column(垂直排列)

功能说明

Column是垂直方向的线性布局容器,子组件从上到下依次排列。这是最基础、最常用的布局之一。

核心属性

属性

类型

说明

space

string | number

子组件间距

justifyContent

FlexAlign

垂直方向对齐方式

alignItems

ItemAlign

水平方向对齐方式

justifyContent可选值:Start(顶部)、Center(居中)、End(底部)、SpaceBetween(两端对齐)、SpaceAround(均匀分布)、SpaceEvenly(等间距)

alignItems可选值:Start(左对齐)、Center(居中)、End(右对齐)、Stretch(拉伸填满)

代码示例

@Entry
@Component
struct ColumnDemo {
  build() {
    Column({ space: 16 }) {
      Text('Column布局示例')
        .fontSize(24)
        .fontWeight(FontWeight.Bold)

      Text('第一项内容')
        .width('100%')
        .height(60)
        .backgroundColor('#E3F2FD')
        .textAlign(TextAlign.Center)
        .borderRadius(8)

      Text('第二项内容')
        .width('100%')
        .height(60)
        .backgroundColor('#BBDEFB')
        .textAlign(TextAlign.Center)
        .borderRadius(8)

      Text('第三项内容')
        .width('100%')
        .height(60)
        .backgroundColor('#90CAF9')
        .textAlign(TextAlign.Center)
        .borderRadius(8)
    }
    .width('100%')
    .height('100%')
    .padding(16)
    .justifyContent(FlexAlign.Center)
    .alignItems(ItemAlign.Center)
  }
}

适用场景

  • 表单页面(登录、注册)

  • 垂直列表项

  • 设置页面

  • 详情页内容区域


2. 线性布局 Row(水平排列)

功能说明

Row是水平方向的线性布局容器,子组件从左到右依次排列。常用于工具栏、导航栏等水平排列场景。

核心属性

属性

类型

说明

space

string | number

子组件间距

justifyContent

FlexAlign

水平方向对齐方式

alignItems

ItemAlign

垂直方向对齐方式

代码示例

@Entry
@Component
struct RowDemo {
  build() {
    Column({ space: 16 }) {
      // 工具栏示例
      Row({ space: 12 }) {
        Button('返回')
          .type(ButtonType.Normal)
          .borderRadius(20)

        Text('页面标题')
          .fontSize(20)
          .fontWeight(FontWeight.Bold)
          .layoutWeight(1)
          .textAlign(TextAlign.Center)

        Button('更多')
          .type(ButtonType.Normal)
          .borderRadius(20)
      }
      .width('100%')
      .height(56)
      .padding({ left: 16, right: 16 })
      .backgroundColor('#F5F5F5')
      .borderRadius(12)

      // 标签页示例
      Row({ space: 0 }) {
        ForEach(['全部', '待付款', '待发货', '已完成'], (item: string) => {
          Text(item)
            .fontSize(14)
            .layoutWeight(1)
            .height(44)
            .textAlign(TextAlign.Center)
            .borderRadius({ bottomLeft: 8, bottomRight: 8 })
            .backgroundColor(item === '全部' ? '#2196F3' : 'transparent')
            .fontColor(item === '全部' ? '#FFFFFF' : '#666666')
        })
      }
      .width('100%')
      .backgroundColor('#FFFFFF')
    }
    .width('100%')
    .height('100%')
    .padding(16)
  }
}

适用场景

  • 顶部导航栏

  • 底部TabBar

  • 水平标签页

  • 操作按钮组


3. 层叠布局 Stack(重叠排列)

功能说明

Stack是层叠布局容器,子组件按照添加顺序依次堆叠,后添加的组件显示在上层。适合实现叠加效果,如角标、遮罩层等。

核心属性

属性

类型

说明

alignContent

Alignment

子组件对齐方式

alignContent可选值:TopStart、Top、TopEnd、Start、Center、End、BottomStart、Bottom、BottomEnd

代码示例

@Entry
@Component
struct StackDemo {
  build() {
    Column({ space: 24 }) {
      // 头像+角标示例
      Stack({ alignContent: Alignment.BottomEnd }) {
        Image($r('app.media.avatar'))
          .width(80)
          .height(80)
          .borderRadius(40)

        Text('3')
          .fontSize(12)
          .fontColor('#FFFFFF')
          .backgroundColor('#FF4444')
          .borderRadius(10)
          .width(20)
          .height(20)
          .textAlign(TextAlign.Center)
          .translate({ x: 4, y: 4 })
      }
      .width(88)
      .height(88)

      // 卡片+角标示例
      Stack({ alignContent: Alignment.TopEnd }) {
        Column() {
          Text('商品名称')
            .fontSize(18)
            .fontWeight(FontWeight.Bold)
          Text('¥99.00')
            .fontSize(16)
            .fontColor('#FF4444')
            .margin({ top: 8 })
        }
        .width(200)
        .height(120)
        .backgroundColor('#FFFFFF')
        .borderRadius(12)
        .padding(16)

        Text('HOT')
          .fontSize(10)
          .fontColor('#FFFFFF')
          .backgroundColor('#FF6B00')
          .borderRadius({ topLeft: 12, bottomLeft: 12 })
          .padding({ left: 8, right: 8, top: 4, bottom: 4 })
      }
    }
    .width('100%')
    .height('100%')
    .padding(16)
    .justifyContent(FlexAlign.Center)
    .alignItems(ItemAlign.Center)
  }
}

适用场景

  • 头像右上角消息角标

  • 商品卡片促销标签

  • 图片叠加文字水印

  • 悬浮按钮覆盖内容


4. 相对布局 RelativeContainer

功能说明

RelativeContainer是相对布局容器,子组件可以相对于父容器或其他子组件进行定位。适合实现复杂的不规则布局。

核心属性

属性

类型

说明

alignRules

AlignRuleOption

相对对齐规则

对齐规则关键属性

  • top / bottom / left / right:相对于目标组件的边

  • alignContentX / alignContentY:相对于父容器的对齐

代码示例

@Entry
@Component
struct RelativeContainerDemo {
  build() {
    RelativeContainer() {
      // 左上角标题
      Text('标题')
        .fontSize(20)
        .fontWeight(FontWeight.Bold)
        .id('title')
        .alignRules({
          top: { anchor: '__container__', align: VerticalAlign.Top },
          left: { anchor: '__container__', align: HorizontalAlign.Start }
        })

      // 标题下方副标题
      Text('副标题内容')
        .fontSize(14)
        .fontColor('#666666')
        .id('subtitle')
        .alignRules({
          top: { anchor: 'title', align: VerticalAlign.Bottom },
          left: { anchor: 'title', align: HorizontalAlign.Start }
        })

      // 右上角按钮
      Button('编辑')
        .id('editBtn')
        .alignRules({
          top: { anchor: '__container__', align: VerticalAlign.Top },
          right: { anchor: '__container__', align: HorizontalAlign.End }
        })

      // 中间内容区域
      Text('这里是主要内容区域,可以放置文章正文、图片等')
        .fontSize(16)
        .id('content')
        .alignRules({
          top: { anchor: 'subtitle', align: VerticalAlign.Bottom },
          left: { anchor: '__container__', align: HorizontalAlign.Start },
          right: { anchor: '__container__', align: HorizontalAlign.End }
        })
        .margin({ top: 16 })
    }
    .width('100%')
    .height(300)
    .padding(16)
    .backgroundColor('#FAFAFA')
    .borderRadius(12)
  }
}

适用场景

  • 复杂表单布局

  • 不规则UI设计

  • 需要精确定位的界面

  • 多组件交叉依赖的场景


5. Flex弹性布局

功能说明

Flex布局是响应式设计的核心,通过主轴和交叉轴的概念,实现灵活的子组件排列和空间分配。相比Column/Row更加强大。

核心属性

属性

类型

说明

direction

FlexDirection

主轴方向

wrap

FlexWrap

是否换行

justifyContent

FlexAlign

主轴对齐方式

alignItems

ItemAlign

交叉轴对齐方式

alignContent

FlexAlign

多行交叉轴对齐

direction可选值:Row(水平)、Column(垂直)、RowReverse(水平反向)、ColumnReverse(垂直反向)

wrap可选值:NoWrap(不换行)、Wrap(换行)

代码示例

@Entry
@Component
struct FlexDemo {
  build() {
    Column({ space: 16 }) {
      // 标签云示例
      Flex({ wrap: FlexWrap.Wrap, justifyContent: FlexAlign.Start, space: { main: LengthMetrics.vp(8), cross: LengthMetrics.vp(8) } }) {
        ForEach(['鸿蒙', 'ArkUI', 'TypeScript', '移动开发', 'HarmonyOS', '前端', '跨平台'], (tag: string) => {
          Text(tag)
            .fontSize(14)
            .fontColor('#1976D2')
            .backgroundColor('#E3F2FD')
            .borderRadius(16)
            .padding({ left: 12, right: 12, top: 6, bottom: 6 })
        })
      }
      .width('100%')

      // 等分布局
      Flex({ justifyContent: FlexAlign.SpaceEvenly }) {
        ForEach(['首页', '发现', '消息', '我的'], (item: string, index: number) => {
          Column() {
            Text('icon')
              .width(24)
              .height(24)
              .backgroundColor('#2196F3')
              .borderRadius(12)
            Text(item)
              .fontSize(12)
              .margin({ top: 4 })
          }
        })
      }
      .width('100%')
      .height(60)
      .backgroundColor('#FFFFFF')
      .borderRadius(12)
    }
    .width('100%')
    .height('100%')
    .padding(16)
  }
}

适用场景

  • 标签云、流式布局

  • 响应式自适应布局

  • 底部导航栏

  • 等分布局


6. Grid网格布局

功能说明

Grid是网格布局容器,通过定义行列将界面划分为均匀的网格单元,子组件可以占据一个或多个网格。适合实现矩阵式布局。

核心属性

属性

类型

说明

columnsTemplate

string

列定义模板

rowsTemplate

string

行定义模板

columnsGap

Length

列间距

rowsGap

Length

行间距

GridItem属性

  • columnStart / columnEnd:占据列的起止位置

  • rowStart / rowEnd:占据行的起止位置

代码示例

@Entry
@Component
struct GridDemo {
  build() {
    Column({ space: 16 }) {
      // 功能网格示例
      Grid() {
        ForEach([
          { name: '扫码', color: '#4CAF50' },
          { name: '付款', color: '#2196F3' },
          { name: '收款', color: '#FF9800' },
          { name: '转账', color: '#9C27B0' },
          { name: '理财', color: '#F44336' },
          { name: '保险', color: '#00BCD4' },
          { name: '信用', color: '#795548' },
          { name: '更多', color: '#607D8B' }
        ], (item: { name: string, color: string }) => {
          Column() {
            Text('icon')
              .width(48)
              .height(48)
              .backgroundColor(item.color)
              .borderRadius(24)
            Text(item.name)
              .fontSize(14)
              .margin({ top: 8 })
          }
          .padding(16)
        })
      }
      .columnsTemplate('1fr 1fr 1fr 1fr')
      .rowsTemplate('1fr 1fr')
      .columnsGap(8)
      .rowsGap(8)
      .width('100%')
      .height(240)
      .backgroundColor('#FFFFFF')
      .borderRadius(12)

      // 跨列布局示例
      Grid() {
        GridItem() {
          Text('横幅广告')
            .width('100%')
            .height(80)
            .backgroundColor('#FF5722')
            .textAlign(TextAlign.Center)
            .fontColor('#FFFFFF')
            .fontSize(18)
            .borderRadius(8)
        }
        .columnStart(0)
        .columnEnd(3)

        ForEach(['1', '2', '3'], (item: string) => {
          GridItem() {
            Text(item)
              .width('100%')
              .height(60)
              .backgroundColor('#E3F2FD')
              .textAlign(TextAlign.Center)
              .borderRadius(8)
          }
        })
      }
      .columnsTemplate('1fr 1fr 1fr 1fr')
      .rowsTemplate('auto auto')
      .columnsGap(8)
      .rowsGap(8)
      .width('100%')
      .height(160)
      .backgroundColor('#FFFFFF')
      .borderRadius(12)
    }
    .width('100%')
    .height('100%')
    .padding(16)
  }
}

适用场景

  • 九宫格功能入口

  • 图片瀑布流

  • 仪表盘数据展示

  • 跨行跨列的复杂网格


布局选型决策表

布局类型

排列方向

换行支持

重叠支持

相对定位

适用场景

Column

垂直

简单垂直排列

Row

水平

简单水平排列

Stack

层叠

-

叠加效果

RelativeContainer

任意

-

复杂相对定位

Flex

水平/垂直

响应式布局

Grid

网格

-

矩阵布局

选择建议

  • 简单垂直/水平排列 → Column/Row

  • 需要叠加效果 → Stack

  • 复杂相对定位 → RelativeContainer

  • 需要换行或响应式 → Flex

  • 矩阵/网格布局 → Grid


实战:用多种布局组合实现个人主页界面

下面通过一个完整的个人主页界面,展示如何组合使用多种布局:

@Entry
@Component
struct ProfilePage {
  build() {
    // Stack实现背景图+内容叠加
    Stack({ alignContent: Alignment.Top }) {
      // 背景图
      Column()
        .width('100%')
        .height(200)
        .linearGradient({
          direction: GradientDirection.Bottom,
          colors: [['#2196F3', 0.0], ['#1565C0', 1.0]]
        })

      // Column实现整体垂直排列
      Column({ space: 16 }) {
        // 头像区域 - Stack实现头像+角标叠加
        Stack({ alignContent: Alignment.BottomEnd }) {
          Image($r('app.media.avatar'))
            .width(100)
            .height(100)
            .borderRadius(50)
            .border({ width: 3, color: '#FFFFFF' })

          Text('VIP')
            .fontSize(10)
            .fontColor('#FFFFFF')
            .backgroundColor('#FF9800')
            .borderRadius(8)
            .padding({ left: 6, right: 6, top: 2, bottom: 2 })
        }
        .margin({ top: 150 })

        // 用户信息 - Column垂直排列
        Column({ space: 4 }) {
          Text('鸿蒙开发者')
            .fontSize(24)
            .fontWeight(FontWeight.Bold)
          Text('专注HarmonyOS开发 | 分享技术干货')
            .fontSize(14)
            .fontColor('#666666')
        }

        // 数据统计 - Row水平等分
        Row() {
          ForEach([
            { label: '文章', value: '128' },
            { label: '粉丝', value: '5.2k' },
            { label: '获赞', value: '9.8k' }
          ], (item: { label: string, value: string }) => {
            Column({ space: 4 }) {
              Text(item.value)
                .fontSize(20)
                .fontWeight(FontWeight.Bold)
                .fontColor('#1976D2')
              Text(item.label)
                .fontSize(12)
                .fontColor('#999999')
            }
            .layoutWeight(1)
            .alignItems(ItemAlign.Center)
          })
        }
        .width('100%')
        .padding(16)
        .backgroundColor('#FFFFFF')
        .borderRadius(12)

        // 标签云 - Flex弹性换行
        Flex({ wrap: FlexWrap.Wrap, space: { main: LengthMetrics.vp(8), cross: LengthMetrics.vp(8) } }) {
          ForEach(['ArkUI', 'TypeScript', '移动开发', 'HarmonyOS', '前端', '跨平台'], (tag: string) => {
            Text(tag)
              .fontSize(12)
              .fontColor('#1976D2')
              .backgroundColor('#E3F2FD')
              .borderRadius(12)
              .padding({ left: 10, right: 10, top: 4, bottom: 4 })
          })
        }
        .width('100%')

        // 功能网格 - Grid布局
        Grid() {
          ForEach([
            { icon: '📝', name: '我的文章' },
            { icon: '⭐', name: '我的收藏' },
            { icon: '📅', name: '我的日程' },
            { icon: '⚙️', name: '设置' }
          ], (item: { icon: string, name: string }) => {
            Column({ space: 8 }) {
              Text(item.icon)
                .fontSize(28)
              Text(item.name)
                .fontSize(12)
                .fontColor('#333333')
            }
            .padding(16)
          })
        }
        .columnsTemplate('1fr 1fr 1fr 1fr')
        .columnsGap(8)
        .width('100%')
        .backgroundColor('#FFFFFF')
        .borderRadius(12)
      }
      .width('100%')
      .height('100%')
      .padding(16)
    }
    .width('100%')
    .height('100%')
    .backgroundColor('#F5F5F5')
  }
}

布局组合分析

  1. Stack:背景图与内容叠加

  2. Column:整体垂直布局 + 子区域垂直排列

  3. Row:数据统计水平等分

  4. Stack:头像+VIP角标叠加

  5. Flex:标签云弹性换行

  6. Grid:功能入口网格布局


总结

鸿蒙ArkUI的6种布局各有特色,实际开发中往往需要组合使用:

布局

核心优势

学习优先级

Column/Row

简单直观,最常用

★★★★★

Flex

灵活强大,响应式

★★★★☆

Grid

网格布局,跨行列

★★★★☆

Stack

层叠效果,角标必备

★★★☆☆

RelativeContainer

相对定位,复杂场景

★★★☆☆

实践建议

  1. 优先使用Column/Row,能满足80%的布局需求

  2. 需要换行时考虑Flex

  3. 矩阵布局使用Grid

  4. 叠加效果使用Stack

  5. 复杂相对定位使用RelativeContainer

布局是UI开发的基础,熟练掌握这些布局容器,你就能轻松实现任何复杂的界面设计。建议多动手实践,通过实际项目加深理解。


下一篇预告:鸿蒙NEXT开发实战系列第13篇将讲解组件状态管理与数据绑定,敬请期待!

Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐