作为一名鸿蒙生态的开发者,首先要入手的就是页面布局,最基础的页面是要有能力画出来并达到给用户带来良好体验的效果,今天要分享的是鸿蒙开发的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的动画效果,助力打造更加完善的鸿蒙应用体验。期待和欢迎各位鸿蒙开发者们的加入鸿蒙知识共建交流群!!!!!

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐