在响应式界面设计中,栅格布局(Grid Layout)能帮助我们快速实现多列、多断点的经典排版。ArkUI 为我们提供了 GridContainer 组件,使得在 HarmonyOS/OpenHarmony 应用中也能轻松构建灵活的栅格系统,支持不同设备宽度下自动调整列宽和偏移。


一、GridContainer 概念

GridContainer 是一个纵向排布的 栅格布局容器,它会将内部每一行(Row)视作一组“格子”,根据设置的总列数、间距、外边距、设备类型等参数,为每个子组件计算其跨列数和偏移量。常见于大屏幕 / Web 端排版,但在移动端通过不同断点同样能做出平板与手机的自适应布局。


二、API 定义

interface GridContainerInterface {
  (options?: GridContainerOptions): GridContainerAttribute;
}

declare interface GridContainerOptions {
  /** 总列数,number 或 "auto" */
  columns?: number | "auto";
  /** 当前使用的设备宽度类型 */
  sizeType?: SizeType;
  /** 列与列之间的水平间距 */
  gutter?: number | string;
  /** 容器左右两侧的外边距 */
  margin?: number | string;
}
  • columns

    • 默认为 "auto",会根据 SizeType 自动选取列数;
    • 指定数字后,不再自动切换。
  • sizeType (SizeType)

    • 指定当前断点类型,改变后内部 useSizeType 配置会生效;
    • 可取:XS, SM, MD, LG, Auto(默认,自动选择)。
  • gutter

    • 水平栅格间距,支持数字(像素)或字符串(如 "10vp");
  • margin

    • 左右两侧整体外边距,同样支持数字或字符串。
declare class GridContainerAttribute extends CommonMethod<GridContainerAttribute> {
  // 目前仅提供基础设置,其它通用方法同其它容器
}

三、子组件跨列与偏移配置

GridContainer 内,每一行建议使用 Row 组件,行内的每个子组件通过 .useSizeType({...}) 来定义它在不同断点下的栅格占用情况:

interface UseSizeTypeOptions {
  xs: { span: number; offset?: number };
  sm?: { span: number; offset?: number };
  md?: { span: number; offset?: number };
  lg?: { span: number; offset?: number };
}
  • span:占用的列数
  • offset:左侧偏移的列数(空白占位)

如果某个断点没有配置,则继续使用上一个断点的设置。


四、完整示例

下面我们演示一个 12 列 栅格、并在手机(XS)、小屏(SM)、中屏(MD)和大屏(LG)四个断点下,不同组件跨列变化的场景,还提供按钮切换断点:

@Entry @Component
struct GridDemo {
  @State sizeType: SizeType = SizeType.Auto;

  build() {
    Column({ space: 10 }) {
      // 栅格容器:12 列,动态断点,间距 10,左右边距 20
      GridContainer({
        columns: 12,
        sizeType: this.sizeType,
        gutter: 10,
        margin: 20
      }) {
        Row() {
          // 第一块:手机占6列,小屏占2,中屏占2,大屏占3
          Text('1')
            .useSizeType({
              xs: { span: 6 },
              sm: { span: 2 },
              md: { span: 2 },
              lg: { span: 3 }
            })
            .height(50)
            .fontSize(20)
            .backgroundColor('#4682B4')
            .textAlign(TextAlign.Center);

          // 第二块:手机占2,小屏占6,中屏占2,大屏占3
          Text('2')
            .useSizeType({
              xs: { span: 2 },
              sm: { span: 6 },
              md: { span: 2 },
              lg: { span: 3 }
            })
            .height(50)
            .fontSize(20)
            .backgroundColor('#00BFFF')
            .textAlign(TextAlign.Center);

          // 第三块:手机占2,小屏占2,中屏占6,大屏占3
          Text('3')
            .useSizeType({
              xs: { span: 2 },
              sm: { span: 2 },
              md: { span: 6 },
              lg: { span: 3 }
            })
            .height(50)
            .fontSize(20)
            .backgroundColor('#4682B4')
            .textAlign(TextAlign.Center);

          // 第四块:手机占2,小屏占2,中屏占2,大屏占3
          Text('4')
            .useSizeType({
              xs: { span: 2 },
              sm: { span: 2 },
              md: { span: 2 },
              lg: { span: 3 }
            })
            .height(50)
            .fontSize(20)
            .backgroundColor('#00BFFF')
            .textAlign(TextAlign.Center);
        }
      }
      .backgroundColor(Color.Pink)
      .width('90%')
      .margin({ top: 10 });

      // 断点切换按钮
      Row({ space: 10 }) {
        ['XS','SM','MD','LG','Auto'].map((label) => {
          Button(label)
            .backgroundColor('#317AFF')
            .onClick(() => {
              // 动态更新断点类型
              this.sizeType = SizeType[label as keyof typeof SizeType];
            });
        });
      }
      .margin({ top: 10 });
    }
    .width('100%');
  }
}

运行效果

  • 切换不同按钮后,四个文字块的宽度会根据断点设定自动变化,并保持总列数不变。
  • gutter 保证了不同块之间固定间距,margin 保证整体左右两侧留白。

五、实战建议

  1. 移动优先

    • 在小屏(xs)下先规划好基础 span,再向上扩展到 smmdlg,遵循“移动优先”设计。
  2. 合理设置间距

    • gutter 决定了列间空隙,不宜过大影响紧凑排版,也不宜过小导致拥挤。
  3. 动态切换

    • 在调试界面中加入断点切换按钮(如示例),迅速查看各断点布局效果。
  4. 嵌套使用

    • GridContainer 内的 Row 里也可嵌套其他容器(如 FlexColumn)实现更复杂布局。
  5. 内容优先,列次之

    • 当某个模块内容高度/宽度变化较大时,可使用 offset 调整横向偏移,确保留白和可读性。

六、小结

  • GridContainer 为 ArkUI 带来了经典的“12 栅格”响应式布局能力;
  • 通过 columnssizeTypeguttermargin 四个参数控制整体网格;
  • 子组件通过 .useSizeType({ xs, sm, md, lg }) 定义不同断点下的跨列与偏移;
  • 配合按钮或者媒体查询实时切换断点,快速验证排版效果;
  • 适用于图文列表、仪表盘、表单、卡片式布局等多种场景。

掌握了这一套,ArkUI 也能像前端 Web 一样,用栅格系统轻松应对各种设备尺寸,实现流畅、优雅的响应式排版。

Logo

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

更多推荐