一、前言

在鸿蒙(HarmonyOS)应用开发中,ArkUI(方舟 UI) 是官方主推的声明式 UI 框架,凭借简洁的语法、高效的渲染能力,成为构建鸿蒙界面的核心工具。而布局作为 UI 开发的基石,决定了页面组件的排列、对齐与展示效果,掌握主流布局组件是入门 ArkUI 的必经之路。

本文结合官方基础知识点与实战案例,从零讲解 ArkUI 三大基础装饰器、五大常用布局(Column、Row、Stack、Flex、相对布局),搭配完整可运行代码,适合鸿蒙开发新手系统学习、实操练习。

二、ArkUI 三大核心装饰器(布局前置基础)

在编写任何布局代码前,必须先了解 ArkUI 规定的三大基础装饰器,这是所有自定义组件和页面的准入规则,缺一不可:

2. 核心常用属性

Column属性逻辑一致,仅排列方向不同:

案例采用Stack + Row + Column 多层嵌套,模拟 APP 个人主页经典样式,是开发中高频组合用法:

2. 完整实战案例(头像 + VIP 角标 嵌套
  1. @Entry页面入口装饰器,用于标记当前自定义组件为独立页面,被该装饰器修饰的组件可以直接在模拟器 / 设备上运行,一个页面有且仅有一个入口组件。
  2. @Component自定义 UI 组件装饰器,用于定义可复用的界面结构体,所有 UI 布局、组件都需要依托该装饰器创建。
  3. @build组件构建方法,所有 UI 布局、子组件都必须编写在build()方法内部,是界面渲染的核心入口。
    @Entry
    @Component
    struct 自定义组件名 {
      // 1. 数据定义区域(ArkTS 变量、状态数据)
      变量名: 类型 = 初始值
    
      // 2. UI布局渲染区域(所有布局写在此处)
      build() {
        // 布局容器 + 子组件
      }
    }
    

    三、五大核心布局详解 + 实战代码

    (一)Column 垂直线性布局

    1. 核心概念

    Column 是垂直布局容器,子组件默认从上到下依次排列

  4. 主轴:垂直方向(上下)
  5. 交叉轴:水平方向(左右)
  6. 个人信息页、表单、列表、竖向文本展示等绝大多数竖向页面适用场景
    2. 核心常用属性
    作用
    space 统一设置子组件间距(官方推荐,替代 margin,界面更整洁)
    justifyContent 主轴(垂直)对齐:居顶、居中、居底、均分
    alignItems 交叉轴(水平)对齐:左对齐、居中、右对齐
    width / height 容器尺寸,100% 代表铺满全屏
    backgroundColor 容器背景色
    padding 容器内边

    3. 完整实战案例(个人信息页面)
    @Entry
    @Component
    struct ColumnPersonPage {
      build() {
        // 垂直布局,子组件间距18
        Column({ space: 18 }) {
          Text("个人信息中心")
            .fontSize(30)
            .fontWeight(FontWeight.Bold)
            .margin({ bottom: 10 })
          Text("姓名:张三").fontSize(22)
          Text("专业:移动应用开发").fontSize(22)
          Text("年级:2025级").fontSize(22)
          Text("学号:2025001001").fontSize(22)
        }
        // 容器铺满全屏
        .width('100%')
        .height('100%')
        // 主轴垂直居中
        .justifyContent(FlexAlign.Center)
        // 交叉轴水平居中
        .alignItems(HorizontalAlign.Center)
        .backgroundColor(0xFFFFFF)
        .padding(30)
      }
    }
    

    (二)Row 水平线性布局

    1. 核心概念

    Row 是水平布局容器,子组件默认从左到右依次排列

  7. 主轴:水平方向(左右)
  8. 交叉轴:垂直方向(上下)
  9. 适用场景:导航栏、按钮组、图标 + 文字、横向功能模块等Huawei Developer。
  10. space:子组件横向间距
  11. justifyContent:主轴(水平)对齐(左、中、右)
  12. alignItems:交叉轴(垂直)对齐(上、中、下)
    @Entry
    @Component
    struct RowAlignDemo {
      build() {
        // 外层垂直布局,分组展示不同对齐效果
        Column({ space: 30 }) {
          // 1. 左对齐按钮组
          Row({ space: 20 }) {
            Button("左1").width(80).height(35)
            Button("左2").width(80).height(35)
          }
          .width('100%')
          .justifyContent(FlexAlign.Start)
    
          // 2. 居中对齐按钮组
          Row({ space: 20 }) {
            Button("中1").width(80).height(35)
            Button("中2").width(80).height(35)
          }
          .width('100%')
          .justifyContent(FlexAlign.Center)
    
          // 3. 右对齐按钮组
          Row({ space: 20 }) {
            Button("右1").width(80).height(35)
            Button("右2").width(80).height(35)
          }
          .width('100%')
          .justifyContent(FlexAlign.End)
        }
        .width('100%')
        .height('100%')
        .padding(20)
      }
    }
    

    (三)Stack 层叠布局

    1. 核心概念

    Stack 是层叠布局容器,子组件默认居中叠加渲染,后编写的组件会覆盖先编写的组件,无固定横竖排列规则。

  13. 核心特点:组件叠加、悬浮覆盖
  14. 适用场景:头像角标、图片水印、Banner 海报、悬浮按钮、弹窗提示、图文叠加等。
@Entry
@Component
struct StackNestDemo {
  build() {
    Column({ space: 30 }) {
      Text("个人主页")
        .fontSize(30)
        .fontWeight(FontWeight.Bold)

      // 水平布局:左侧头像 + 右侧个人介绍
      Row({ space: 20 }) {
        // 层叠布局:圆形头像 + VIP角标
        Stack() {
          // 底层:圆形头像图片
          Image($r('app.media.start_icon'))
            .width(100)
            .height(100)
            .borderRadius(50)
          // 上层:VIP标签(覆盖在图片上)
          Text("VIP")
            .fontSize(14)
            .fontColor(Color.White)
            .backgroundColor(0xFF3333)
            .padding(4)
            .borderRadius(6)
        }

        // 右侧文本信息(垂直排列)
        Column({ space: 10 }) {
          Text("鸿蒙开发者")
            .fontSize(22)
            .fontWeight(FontWeight.Medium)
          Text("专注鸿蒙应用开发实训")
            .fontSize(18)
            .fontColor(Color.Gray)
        }
      }
    }
    .width('100%')
    .height('100%')
    .justifyContent(FlexAlign.Center)
    .alignItems(HorizontalAlign.Center)
    .backgroundColor(0xFFFFFF)
  }
}

(四)Flex 弹性布局

1. 核心概念

Flex 弹性布局是线性布局的升级版,支持自适应屏幕、子组件超出容器自动换行,适配不同尺寸鸿蒙设备,是复杂流式布局的首选。

  • 核心优势:自动换行、比例分配空间、灵活对齐
  • 适用场景:标签云、功能标签组、流式按钮、自适应菜单等。
2. 核心常用属性
  • wrap: FlexWrap.Wrap:开启自动换行(核心属性)
  • space:子组件统一间距
  • justifyContent:主轴对齐方式
    @Entry
    @Component
    struct FlexBaseDemo {
      build() {
        // 弹性布局:自动换行 + 子组件间距12
        Flex({ wrap: FlexWrap.Wrap, space: 12 }) {
          Text("鸿蒙基础")
            .padding({ left: 12, right: 12, top: 6, bottom: 6 })
            .backgroundColor(0xE8F4FF)
            .borderRadius(20)
            .fontSize(16)
          Text("ArkTS语法")
            .padding({ left: 12, right: 12, top: 6, bottom: 6 })
            .backgroundColor(0xE8F4FF)
            .borderRadius(20)
            .fontSize(16)
          Text("ArkUI布局")
            .padding({ left: 12, right: 12, top: 6, bottom: 6 })
            .backgroundColor(0xE8F4FF)
            .borderRadius(20)
            .fontSize(16)
          Text("组件开发")
            .padding({ left: 12, right: 12, top: 6, bottom: 6 })
            .backgroundColor(0xE8F4FF)
            .borderRadius(20)
            .fontSize(16)
          Text("页面跳转")
            .padding({ left: 12, right: 12, top: 6, bottom: 6 })
            .backgroundColor(0xE8F4FF)
            .borderRadius(20)
            .fontSize(16)
          Text("数据存储")
            .padding({ left: 12, right: 12, top: 6, bottom: 6 })
            .backgroundColor(0xE8F4FF)
            .borderRadius(20)
            .fontSize(16)
        }
        .width('100%')
        .padding(20)
      }
    }
    

    (五)相对布局(RelativeContainer)

    1. 核心概念

    相对布局(RelativeContainer)是自由度极高的布局,不限制固定排列方向,通过锚点规则(alignRules) 让子组件参照其他组件的位置进行定位,适合需要精确定位、不规则布局的页面。

  • 核心逻辑:给组件设置唯一id,其他组件通过anchor锚定目标组件,再设置上下左右对齐规则。
  • 适用场景:复杂自定义页面、不规则控件布局、精准定位元素。
    @Entry
    @Component
    struct RelativeLayoutDemo {
      build() {
        RelativeContainer() {
          // 基准按钮(锚点参照组件)
          Button("基准按钮")
            .id('buttonid1')
            .width(120)
            .height(40)
            .position({ x: 50, y: 50 })
    
          // 图片组件:参照基准按钮,位于按钮下方,左对齐
          Image($r('app.media.first'))
            .width('97%')
            .id('image1')
            .alignRules({
              top: { anchor: 'buttonid1', align: VerticalAlign.Bottom },
              left: { anchor: 'buttonid1', align: HorizontalAlign.Start }
            })
            .margin({ top: 30 })
        }
        .width('100%')
        .height('100%')
      }
    }
    

    四、拓展布局预告

    除以上五大基础布局外,ArkUI 还提供两大高频进阶布局,后续可深入学习:

  • 轮播图(Swiper):用于首页 Banner、图片轮播、引导页,支持自动轮播、手势滑动。
  • Tabs 标签页:主流 APP 顶部 / 底部标签栏,实现页面快速切换(首页、分类、我的等模块)。

    五、布局选型总结(新手速记)

    布局组件 排列方式 核心场景 优先级
    Column 垂直从上到下 表单、列表、竖向文本 最高(基础首选)
    Row 水平从左到右 按钮组、导航、横向模块 最高(基础首选)
    Stack 层叠覆盖 头像角标、水印、悬浮按钮 中(叠加场景专用)
    Flex 自适应 + 自动换行 标签组、流式布局、多设备适配 中(流式布局首选)
    RelativeContainer 相对锚点定位 不规则页面、精准定位 低(复杂布局使用)

    开发小技巧:实际项目中多布局嵌套是常态(Column + Row、Stack + Row),优先使用space设置间距,减少margin滥用,让代码更规范、维护更简单。

    六、最后

    ArkUI 布局是鸿蒙 UI 开发的地基,新手建议先吃透ColumnRow两大线性布局,再逐步掌握Stack层叠、Flex弹性布局,最后学习相对布局、轮播、Tabs 等进阶组件。

 布局

一、什么是垂直布局 Column

Column 是 ArkUI 提供的垂直线性布局,内部所有子组件默认从上到下依次垂直排列,是开发中最常用的基础布局。页面规范:一个页面只能有唯一根布局,Column 可以作为根布局,内部嵌套 Row、Stack、Flex、RelativeContainer 等其他布局。

二、核心常用属性
  1. space(number):子组件之间垂直间距
  2. justifyContent(FlexAlign):主轴(垂直)对齐方式
    • FlexAlign.Start:顶部对齐
    • FlexAlign.Center:垂直居中
    • FlexAlign.End:底部对齐
    • FlexAlign.SpaceBetween:两端贴边,中间均分间距
  3. alignItems(ItemAlign):交叉轴(水平)对齐
    • ItemAlign.Center:子组件水平居中
  4. width/height:布局宽高,推荐 100% 占满屏幕
三、完整可运行代码

ets

@Entry
@Component
struct ColumnBlogDemo {
  build() {
    // 唯一根布局:垂直布局Column
    Column() {
      Text("用户信息卡片")
        .fontSize(24)
        .fontWeight(FontWeight.Bold)
        .margin({ bottom: 10 })

      Text("姓名:张三")
        .width("100%")
        .height(50)
        .backgroundColor("#f5f5f5")
        .borderRadius(8)
        .textAlign(TextAlign.Start)
        .padding({ left: 15 })

      Text("年龄:22")
        .width("100%")
        .height(50)
        .backgroundColor("#f5f5f5")
        .borderRadius(8)
        .textAlign(TextAlign.Start)
        .padding({ left: 15 })

      Text("手机号:13800138000")
        .width("100%")
        .height(50)
        .backgroundColor("#f5f5f5")
        .borderRadius(8)
        .textAlign(TextAlign.Start)
        .padding({ left: 15 })
    }
    .width("100%")
    .height("100%")
    .padding(20)
    .space(12) // 子组件垂直间距
    .justifyContent(FlexAlign.Center) // 整体垂直居中
    .alignItems(ItemAlign.Start)
  }
}
四、适用业务场景
  • 表单页面、个人中心、详情页、列表条目、弹窗内容区
  • 作为页面根布局,嵌套横向导航、标签、图片等组件
五、注意事项
  1. Column 子组件超出高度会直接截断,不会自动换行;需要自动换行使用 Flex 弹性布局
  2. 避免多层 Column 嵌套,会降低页面渲染性能

一、Row 水平布局概念

Row 为水平线性布局,子组件从左至右横向依次排列,常用于导航、底部 Tab、按钮操作栏。同样遵循页面规则:整个页面只能有一个根布局,Row 可做根布局,也可嵌套在 Column 内部。

二、核心 API 属性
  • space():子组件水平间距
  • justifyContent:水平主轴对齐
  • alignItems:垂直交叉轴对齐
  • 宽高、内边距、外边距通用样式
三、完整示例代码

ets

@Entry
@Component
struct RowBlogDemo {
  build() {
    Column() {
      Text("底部操作按钮栏").fontSize(22).margin({ bottom: 20 })
      // 水平布局Row
      Row() {
        Button("取消", { stateEffect: true })
          .width(120)
          .height(44)
          .fontSize(18)
          .fontColor("#333")
          .backgroundColor("#eee")
        Button("保存草稿", { stateEffect: true })
          .width(120)
          .height(44)
          .fontSize(18)
          .backgroundColor("#666")
        Button("提交", { stateEffect: true })
          .width(120)
          .height(44)
          .fontSize(18)
          .backgroundColor("#007DFF")
      }
      .width("100%")
      .space(15)
      .justifyContent(FlexAlign.Center) // 按钮整体水平居中
    }
    .width("100%")
    .height("100%")
    .padding(20)
  }
}
四、使用场景
  1. 页面顶部导航栏、底部 Tab 菜单
  2. 表单同行多个按钮、单选选项横向排列
  3. 商品图文横向卡片、头像 + 名称一行展示
五、缺点

子组件总宽度超过 Row 宽度时,组件会被截断,不会自动换行;多标签流式布局请用 Flex。

一、相对布局介绍

RelativeContainer 相对布局,核心逻辑是以参照物定位组件:参照物分为父容器__container__、其他组件 id。无需多层嵌套,就能实现左上、右下、居中、组件左右上下相邻等复杂布局。

二、核心关键
  1. 每个子组件必须设置唯一 .id("标识")
  2. .alignRules() 配置上下左右、居中约束规则
  3. 锚点 anchor 指定参照物
三、完整可运行代码

ets

@Entry
@Component
struct RelativeBlogDemo {
  build() {
    RelativeContainer() {
      // 左上方块
      Text("左上")
        .width(100)
        .height(100)
        .backgroundColor("#7B68EE")
        .fontColor("#fff")
        .textAlign(TextAlign.Center)
        .alignRules({
          top: { anchor: "__container__", align: VerticalAlign.Top },
          left: { anchor: "__container__", align: HorizontalAlign.Start }
        })
        .id("box1")

      // box1右侧方块
      Text("右邻box1")
        .width(100)
        .height(100)
        .backgroundColor("#FF6347")
        .fontColor("#fff")
        .textAlign(TextAlign.Center)
        .alignRules({
          top: { anchor: "box1", align: VerticalAlign.Top },
          left: { anchor: "box1", align: HorizontalAlign.End }
        })
        .id("box2")

      // 底部居中文字
      Text("页面底部居中")
        .width("80%")
        .height(60)
        .backgroundColor("#32CD32")
        .fontColor("#fff")
        .textAlign(TextAlign.Center)
        .alignRules({
          bottom: { anchor: "__container__", align: VerticalAlign.Bottom },
          centerX: { anchor: "__container__" }
        })
        .id("footer")
    }
    .width("100%")
    .height("100%")
    .padding(30)
  }
}
四、适用场景
  • 复杂不规则页面、浮标、角落悬浮按钮
  • 需要组件互相参照摆放,减少布局嵌套层级
五、踩坑提示

约束不能循环依赖(A 锚定 B,B 又锚定 A),会渲染异常。

一、Stack 层叠布局原理

Stack 帧布局 / 层叠布局,所有子组件统一堆叠在同一坐标系,后声明的组件层级更高,覆盖在先写组件上方。可统一设置内部子组件对齐方式 alignContent

二、典型业务场景
  1. 图片上叠加播放按钮、文字遮罩(Banner 轮播)
  2. 全局加载遮罩、弹窗浮层
  3. 多页面切换容器、登录浮窗
三、完整代码示例

ets

@Entry
@Component
struct StackBlogDemo {
  build() {
    Column() {
      Text("轮播图示例-层叠布局").fontSize(22).margin({ bottom: 15 })
      // 层叠布局
      Stack({ alignContent: Alignment.Center }) {
        // 底层:背景图
        Text("背景大图")
          .width(320)
          .height(180)
          .backgroundColor("#cccccc")
          .fontSize(28)
          .textAlign(TextAlign.Center)
        // 中层:半透明遮罩
        Rect()
          .width(320)
          .height(180)
          .fill("rgba(0,0,0,0.3)")
        // 顶层:按钮
        Button("点击播放", { stateEffect: true })
          .fontSize(18)
          .backgroundColor("#ffffff")
          .fontColor("#000000")
      }
    }
    .width("100%")
    .height("100%")
    .padding(20)
  }
}
四、核心属性

Stack({ alignContent: Alignment.Center }):统一设置所有子组件居中对齐,可选 Top、Bottom、Start、End 等。

一、Flex 布局介绍

Flex 弹性布局是 Row/Column 的升级版,兼容前端 CSS Flex 弹性盒特性,支持自动换行,完美解决水平布局组件溢出截断问题。

二、核心配置参数

typescript

Flex({
  direction: FlexDirection.Row, // 主轴水平/Column垂直
  wrap: FlexWrap.Wrap, // Wrap自动换行,NoWrap不换行
  justifyContent: FlexAlign.SpaceEvenly, // 主轴均分
  alignItems: ItemAlign.Center // 交叉轴居中
})
三、完整标签流代码

ets

@Entry
@Component
struct FlexBlogDemo {
  // 模拟热词数组
  hotTagList: string[] = ["数码","手机","电脑","平板","耳机","手表","相机","充电宝","数据线"]
  build() {
    Column() {
      Text("搜索热门标签").fontSize(22).margin({ bottom: 15 })
      Flex({
        direction: FlexDirection.Row,
        wrap: FlexWrap.Wrap, // 空间不足自动换行
        justifyContent: FlexAlign.Start,
        alignItems: ItemAlign.Center
      }) {
        ForEach(this.hotTagList, (tag: string) => {
          Text(tag)
            .padding({ left: 14, right: 14, top: 6, bottom: 6 })
            .margin({ right: 10, bottom: 12 })
            .backgroundColor("#E6F4FF")
            .fontSize(16)
            .borderRadius(20)
        })
      }
      .width("100%")
    }
    .width("100%")
    .height("100%")
    .padding(20)
  }
}
四、适用场景
  • 商品分类标签、搜索热词、多筛选条件按钮
  • 自适应多列流式卡片、九宫格简易布局
五、对比 Row

Row 不支持换行,超出宽度直接隐藏;Flex 开启 Wrap 后自动换行,开发标签页优先使用 Flex。

1. Swiper 轮播图组件

用于首页 Banner、广告轮播,支持自动轮播、指示器。

ets

Swiper() {
  Text("轮播1").width("100%").height(160).backgroundColor("#87CEEB").textAlign(TextAlign.Center)
  Text("轮播2").width("100%").height(160).backgroundColor("#98FB98").textAlign(TextAlign.Center)
  Text("轮播3").width("100%").height(160).backgroundColor("#FFD700").textAlign(TextAlign.Center)
}
.autoPlay(true) // 自动播放
.loop(true) // 循环轮播
.indicator(true) // 显示底部圆点指示器
.width("100%")
.height(160)

2. Video 视频播放组件

本地 / 网络视频播放,自带播放控制器

ets

Video($r("sys.media.video_demo"))
  .width("100%")
  .height(200)
  .controls(true) // 显示播放控件
  .autoPlay(false)

3. Image 图片组件

加载本地资源、网络图片,支持缩放、圆角

ets

Image($r("sys.media.ohos_ic_public_pic"))
  .width(120)
  .height(120)
  .borderRadius(12)
  .objectFit(ImageFit.Cover)

4. Tabs 选项卡组件

顶部分类 Tab 切换页面

ets

Tabs() {
  TabContent() { Text("首页内容页") }.tabBar(Text("首页"))
  TabContent() { Text("分类内容页") }.tabBar(Text("分类"))
  TabContent() { Text("我的页面") }.tabBar(Text("我的"))
}
.barWidth("100%")
.barHeight(50)

5. Text 文本 / TextInput 输入框(表单核心)

ets

Column() {
  Text("用户名:").fontSize(18)
  TextInput({ text: "", placeholder: "请输入账号" })
    .width("100%")
    .height(48)
    .margin({ bottom: 15 })

  Text("密码:").fontSize(18)
  TextInput({ text: "", placeholder: "请输入密码" })
    .width("100%")
    .height(48)
    .type(InputType.Password) // 密码框
}

6. Button 按钮组件

点击交互核心组件,支持自定义颜色圆角

ets

Row() {
  Button("普通按钮")
  Button("蓝色主按钮").backgroundColor("#007DFF")
  Button("圆角按钮").borderRadius(24)
}.space(12)

7. Radio 单选框

互斥单选选择,配合 RadioGroup 使用

ets

RadioGroup({ group: "sexGroup" }) {
  Row() {
    Radio({ value: "man", group: "sexGroup" })
    Text("男")
    Radio({ value: "woman", group: "sexGroup" }).margin({ left: 20 })
    Text("女")
  }
}

8. Toggle 开关组件

设置页开关、功能启用 / 关闭

ets

Row() {
  Text("自动播放:")
  Toggle({ type: ToggleType.Switch, isOn: false })
}.width("100%")
.justifyContent(FlexAlign.SpaceBetween)

Logo

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

更多推荐