在 HarmonyOS ArkTS 页面开发中,布局是 UI 搭建的基础。日常项目高频使用选项卡 Tabs、轮播 Swiper、相对布局 RelativeContainer三大核心组件,本文结合课堂宿舍实战案例,从原理、API、实战代码、使用场景梳理。

一、整体组件分类梳理

组件核心作用适用场景
Tabs 选项卡多页面分类切换,生成底部 / 顶部导航栏APP 首页底部导航(首页 / 发现 / 我的)、分类标签页
Swiper 轮播横向滑动切换多页面,支持自动轮播、循环、指示器广告轮播、宿舍床位轮播、图片横幅
RelativeContainer 相对布局组件之间互相锚定、相对定位,减少布局嵌套不规则排版、多组件错落排布(宿舍床位卡片排版)

二、组件详解和实战代码(结合宿舍项目案例)

1. Tabs 选项卡:多标签页面切换

1.1 原理说明

Tabs 由Tabs容器 + TabContent页面 + tabBar导航文字三部分组成:

  1. 一个TabContent对应一个页面 + 底部一个导航按钮
  2. .tabBar("文字")紧跟 TabContent 后,定义底部标签显示内容;
  3. .barPosition(BarPosition.Bottom/Top)控制导航栏在页面底部 / 顶部。
1.2 实战:宿舍三级标签(宿舍介绍 / 床位轮播 / 床位详情)
@Entry
@Component
struct LianXi4 {
  build() {
    // Tabs外层标签容器
    Tabs() {
      // 标签1:宿舍介绍页
      TabContent() {
        Text('欢迎来到新宿舍,下面是宿舍信息情况')
          .width('100%').height(100).fontSize(35)
      }.padding(10)
      .tabBar('宿舍') // 底部导航文字

      // 标签2:床位轮播页(内嵌Swiper轮播)
      TabContent() {
        Swiper() {
          Text('一号铺').width('100%').height(100).backgroundColor(Color.Blue).fontSize(35)
          Text('二号铺').width('100%').height(100).backgroundColor(Color.Pink).fontSize(35)
          Text('三号铺').width('100%').height(100).backgroundColor(Color.Brown).fontSize(35)
          Text('四号铺').width('100%').height(100).backgroundColor(Color.Red).fontSize(35)
          Text('五号铺').width('100%').height(100).backgroundColor(Color.Orange).fontSize(35)
        }
        .width('100%').height(100)
        .indicator(true)    // 开启轮播圆点指示器
        .autoPlay(true)     // 开启自动轮播
        .interval(300)      // 轮播间隔300ms
        .loop(true)         // 首尾无限循环
      }.padding(10)
      .tabBar('名字')

      // 标签3:床位详情页(内嵌RelativeContainer相对布局)
      TabContent() {
        RelativeContainer() {
          // 一号铺:锚定父容器左上角
          Text('517一号铺').id('title').fontSize(28).padding(10).backgroundColor(Color.Green)
            .alignRules({
              top:{anchor:'__container__',align:VerticalAlign.Top},
              left:{anchor:'__container__',align:HorizontalAlign.Start}
            })
          // 二号铺:锚定一号铺右侧
          Text('517二号铺').id('title1').fontSize(28).padding(10).backgroundColor(Color.Gray)
            .alignRules({
              top:{anchor:'title',align:VerticalAlign.Top},
              left:{anchor:'title',align:HorizontalAlign.End}
            })
          // 三号铺:锚定一号铺下方
          Text('517三号铺').id('title2').fontSize(28).padding(10).backgroundColor(Color.Gray)
            .alignRules({
              top:{anchor:'title',align:VerticalAlign.Bottom},
              left:{anchor:'title',align:HorizontalAlign.Start}
            })
          // 后续4~8号铺依次锚定前一个组件排版
          Text('517四号铺').id('title3').fontSize(28).padding(10).backgroundColor(Color.Orange)
            .alignRules({top:{anchor:'title2',align:VerticalAlign.Top},left:{anchor:'title2',align:HorizontalAlign.End}})
          Text('517五号铺').id('title4').fontSize(28).padding(10).backgroundColor(Color.Blue)
            .alignRules({top:{anchor:'title2',align:VerticalAlign.Bottom},left:{anchor:'title2',align:HorizontalAlign.Start}})
          Text('517六号铺').id('title5').fontSize(28).padding(10).backgroundColor(Color.Brown)
            .alignRules({top:{anchor:'title4',align:VerticalAlign.Top},left:{anchor:'title4',align:HorizontalAlign.End}})
          Text('517七号铺').id('title6').fontSize(28).padding(10).backgroundColor(Color.Gray)
            .alignRules({top:{anchor:'title4',align:VerticalAlign.Bottom},left:{anchor:'title4',align:HorizontalAlign.Start}})
          Text('517八号铺').id('title7').fontSize(28).padding(10).backgroundColor(Color.Orange)
            .alignRules({top:{anchor:'title6',align:VerticalAlign.Top},left:{anchor:'title6',align:HorizontalAlign.End}})
        }.height('100%')
      }.tabBar('床号')
    }
    .barPosition(BarPosition.Bottom) // 导航栏放底部
  }
}
1.3 运行效果

页面底部出现【宿舍、名字、床号】三个标签,点击切换对应页面:

  • 宿舍:宿舍简介文字;
  • 名字:床位横向自动轮播;
  • 床号:8 个床位错落相对排版。

2. Swiper 轮播组件:自动横向滑动

2.1 核心属性汇总
属性作用
.indicator(true)开启底部小圆点页码指示器
.autoPlay(true)开启自动播放轮播
.interval(毫秒)自动切换间隔时间,3000=3 秒
.loop(true)开启无限循环,滑到末尾切回第一页
.width/height固定轮播容器尺寸

2.2 最简基础案例

@Entry
@Component
struct SwiperDemo {
  build() {
    Column(){
      Swiper(){
        Text('你好').width('100%').height(100).backgroundColor(Color.Blue).fontSize(35)
        Text('世界').width('100%').height(100).backgroundColor(Color.Pink).fontSize(35)
        Text('伟大').width('100%').height(100).backgroundColor(Color.Brown).fontSize(35)
        Text('中国').width('100%').height(100).backgroundColor(Color.Red).fontSize(35)
        Text('承德').width('100%').height(100).backgroundColor(Color.Orange).fontSize(35)
      }
      .width('100%').height(100)
      .indicator(true).autoPlay(true).interval(300).loop(true)
    }.padding(10)
  }
}

3. RelativeContainer 相对布局:锚点定位精髓

3.1 原理

相对布局不依赖固定坐标,靠锚点(anchor)+ 对齐方式(align)定位

  1. anchor:'__container__':锚定父容器(整个 RelativeContainer);
  2. anchor:'组件id':锚定其他子组件(实现 A 在 B 右边 / 下边);
  3. 水平枚举:HorizontalAlign.Start(靠左)、Center(居中)、End(靠右)
  4. 垂直枚举:VerticalAlign.Top(靠上)、Center(居中)、Bottom(靠下)
3.2 经典案例 1:院校标题上下排版
@Entry
@Component
struct SchoolDemo {
  build() {
    RelativeContainer() {
      // 第一个标题id=title,贴容器左上角
      Text('河北软件职业技术学院').id('title').fontSize(28).fontWeight(FontWeight.Bolder)
        .alignRules({
          top:{anchor:'__container__',align:VerticalAlign.Top},
          left:{anchor:'__container__',align:HorizontalAlign.Start}
        }).padding(10)
      // 第二个标题锚在title底部、左对齐
      Text('计算机应用工程系').id('title2').fontSize(24)
        .alignRules({
          top:{anchor:'title',align:VerticalAlign.Bottom},
          left:{anchor:'title',align:HorizontalAlign.Start}
        }).padding(30)
    }.width('100%').height('100%')
  }
}

3.3 经典案例 2:多方块错落 + 居中按钮

@Entry
@Component
struct RelDemo {
  build() {
    RelativeContainer(){
      Text('相对布局的案例').id('title').fontSize(22).fontWeight(FontWeight.Bold)
        .alignRules({top:{anchor:'__container__',align:VerticalAlign.Top},left:{anchor:'__container__',align:HorizontalAlign.Start}})
        .backgroundColor(Color.Brown).width(150).height(150)
      // 第二个方块在title右侧
      Text('相对布局的案例').id('title2').fontSize(22).fontWeight(FontWeight.Bold)
        .alignRules({top:{anchor:'title',align:VerticalAlign.Top},left:{anchor:'title',align:HorizontalAlign.End}})
        .backgroundColor(Color.Pink).width(150).height(150)
      // 第三个方块在title下方
      Text('相对布局的案例').id('title3').fontSize(22).fontWeight(FontWeight.Bold)
        .alignRules({top:{anchor:'title',align:VerticalAlign.Bottom},left:{anchor:'title',align:HorizontalAlign.Start}})
        .backgroundColor(Color.Gray).width(150).height(150)
      // 第四个方块在title3右侧
      Text('相对布局的案例').id('title4').fontSize(22).fontWeight(FontWeight.Bold)
        .alignRules({top:{anchor:'title3',align:VerticalAlign.Top},left:{anchor:'title3',align:HorizontalAlign.End}})
        .backgroundColor(Color.Green).width(150).height(150)
      // 按钮在页面正中间
      Button('基础按钮').id('basebn').width(100).height(40)
        .alignRules({top:{anchor:'__container__',align:VerticalAlign.Center},left:{anchor:'__container__',align:HorizontalAlign.Center}})
    }
  }
}

4.Stack 层叠布局

1. 原理

层叠布局核心是组件层级堆叠覆盖,子组件按代码书写顺序分层渲染,后定义的组件会覆盖在先定义组件上方,适合浮层、遮罩、图片加文字场景。

  1. 堆叠规则:从上到下书写 = 从底层到顶层渲染;
  2. 定位方式:子组件默认全部居中堆叠,可通过alignContent统一控制所有子组件对齐;

案例:颜色层叠

@Entry
@Component
struct Index {
  build() {
    Stack() {
      Column() {}.width(220).height(220).backgroundColor(Color.Blue)
      Text('鸿蒙实训海报')
        .fontSize(22).fontColor(Color.Orange).backgroundColor(Color.Brown)
        .padding(10).borderRadius(20)
    }
    .width('100%').height('100%')
  }
}

Flex 弹性布局

1. 原理

弹性布局是是最灵活的布局方式,支持自动换行、元素自适应占比,适配多屏幕自适应排版。

换行属性 wrap

  • FlexWrap.NoWrap:不换行,超出直接截断(默认)
  • FlexWrap.Wrap:空间不足自动换行

案例:数学、英语、语文方块

@Entry
@Component
struct Index {
  build() {
    Flex({ wrap: FlexWrap.NoWrap }) {
      Text('数学').width('66%').height(50).backgroundColor('#F5DEB3')
      Text('英语').width('33%').height(50).backgroundColor('#D2B48C')
      Text('语文').width('33%').height(50).backgroundColor('#F5DEB3')
    }
    .height(70).width('90%').padding(10).backgroundColor('#AFEEEE')
  }
}

三、开发避坑总结

  1. 组件命名不能用系统关键字index是系统内置属性,struct index{}会编译报错,新建ArkTS文件写入;
  2. RelativeContainer 必须设置 id:需要被其他组件锚定的控件必须.id('自定义名称'),否则无法引用,切记不可重复;
  3. Tabs 嵌套组件层级:Swiper/RelativeContainer 写在 TabContent 内部,不能直接写在 Tabs 根节点;
  4. 不管哪种布局,他只能有一个根布局,可以在跟布局里面嵌套其他布局

五、总结

Flex 弹性布局

可自由切换横竖方向,支持自动换行,适配多屏幕流式卡片布局。

Stack 层叠布局

子组件按书写顺序层层叠加,后定义的组件覆盖在上层,可统一控制堆叠对齐,适合图片文字遮罩、角标、弹窗浮层、轮播。

 RelativeContainer 相对布局

依靠锚点 + 对齐规则精准定位,可锚定父容器或其他组件 ID,不依赖流式顺序,适合结构不规则、组件互相参照的复杂页面。

垂直布局、水平布局请参照,鸿蒙 ArkUI 入门:三个核心元素与布局文章

如有雷同,请勿追责!

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐