ArkUI Grid:九宫格入口别再手算宽度了

举报
蓝瘦的蜕变 发表于 2026/08/04 15:07:52 2026/08/04
【摘要】 入口宫格、工具面板、固定行列的小卡片,都别再手算宽度了。Grid 负责容器,GridItem 负责每个格子,我们只需要把行列模板写清楚。 先看最常用的三列入口 Demo 第一块用 columnsTemplate('1fr 1fr 1fr') 和 rowsTemplate('1fr 1fr') 做了一个两行三列入口区。

ArkUI Grid:九宫格入口别再手算宽度了

入口宫格、工具面板、固定行列的小卡片,都别再手算宽度了。Grid 负责容器,GridItem 负责每个格子,我们只需要把行列模板写清楚。

先看最常用的三列入口

Demo 第一块用 columnsTemplate('1fr 1fr 1fr')rowsTemplate('1fr 1fr') 做了一个两行三列入口区。

Grid() {
  ForEach(this.entries, (item: GridDemoItem) => {
    GridItem() {
      this.gridCard(item)
    }
  }, (item: GridDemoItem) => item.title)
}
.columnsTemplate('1fr 1fr 1fr')
.rowsTemplate('1fr 1fr')

fr 可以先理解成“按比例分空间”。三段 1fr 就是三列均分。

不均匀网格也先从比例开始

第二块用了 columnsTemplate('2fr 1fr')。左边占两份,右边占一份。它不是复杂跨行跨列,只是先让你看到 Grid 不一定每列都一样宽。

这一篇不讲拖拽排序,也不讲复杂 GridLayoutOptions。入门时先把 Grid / GridItem 和行列模板搞清楚,后面再讲跨行跨列会轻松很多。

你做首页入口时,是更常见三列宫格,还是左右不等宽的信息面板?这会决定你一开始怎么写模板。

参考文档: https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/arkts-list-and-grid

完整示例代码

文件位置:entry/src/main/ets/pages/arkUI/listLayout/ArkUIGridDemo.ets

class GridDemoItem {
  title: string = '';
  desc: string = '';
  color: string = '';
  bgColor: string = '';

  constructor(title: string, desc: string, color: string, bgColor: string) {
    this.title = title;
    this.desc = desc;
    this.color = color;
    this.bgColor = bgColor;
  }
}

@Entry
@Component
struct ArkUIGridDemo {
  private entries: GridDemoItem[] = [
    new GridDemoItem('消息', '12 条', '#2563EB', '#DBEAFE'),
    new GridDemoItem('日程', '3 个', '#0F766E', '#CCFBF1'),
    new GridDemoItem('文件', '28 份', '#7C3AED', '#EDE9FE'),
    new GridDemoItem('收藏', '16 个', '#C2410C', '#FFEDD5'),
    new GridDemoItem('团队', '8 人', '#1D4ED8', '#DBEAFE'),
    new GridDemoItem('设置', '常用', '#334155', '#E2E8F0')
  ];

  @Builder
  sectionTitle(title: string, desc: string) {
    Column({ space: 4 }) {
      Text(title)
        .width('100%')
        .fontSize(16)
        .fontWeight(700)
        .fontColor('#0F172A')

      Text(desc)
        .width('100%')
        .fontSize(13)
        .fontColor('#64748B')
        .lineHeight(20)
    }
    .width('100%')
    .alignItems(HorizontalAlign.Start)
  }

  @Builder
  gridCard(item: GridDemoItem) {
    Column({ space: 8 }) {
      Text(item.title.substring(0, 1))
        .width(38)
        .height(38)
        .fontSize(18)
        .fontWeight(700)
        .fontColor('#FFFFFF')
        .textAlign(TextAlign.Center)
        .backgroundColor(item.color)
        .borderRadius(8)

      Text(item.title)
        .fontSize(15)
        .fontWeight(700)
        .fontColor('#0F172A')

      Text(item.desc)
        .fontSize(12)
        .fontColor('#64748B')
    }
    .width('100%')
    .height('100%')
    .justifyContent(FlexAlign.Center)
    .alignItems(HorizontalAlign.Center)
    .backgroundColor(item.bgColor)
    .borderRadius(8)
  }

  build() {
    Scroll() {
      Column({ space: 18 }) {
        Text('ArkUI Grid')
          .width('100%')
          .fontSize(24)
          .fontWeight(700)
          .fontColor('#0F172A')

        Text('九宫格入口别再手算宽度了')
          .width('100%')
          .fontSize(22)
          .fontWeight(700)
          .fontColor('#111827')

        Text('这一页只看 Grid 和 GridItem。入口宫格、仪表盘小卡片、固定行列内容,都可以先交给 Grid 处理。')
          .width('100%')
          .fontSize(14)
          .fontColor('#64748B')
          .lineHeight(22)

        Column({ space: 12 }) {
          this.sectionTitle('三列入口不用自己算宽度', 'columnsTemplate 写成三段 1fr,Grid 就会把横向空间均分给三列。')

          Grid() {
            ForEach(this.entries, (item: GridDemoItem) => {
              GridItem() {
                this.gridCard(item)
              }
            }, (item: GridDemoItem) => item.title)
          }
          .width('100%')
          .height(260)
          .columnsTemplate('1fr 1fr 1fr')
          .rowsTemplate('1fr 1fr')
          .columnsGap(10)
          .rowsGap(10)
        }
        .width('100%')
        .padding(16)
        .backgroundColor('#EFF6FF')
        .borderRadius(8)

        Column({ space: 12 }) {
          this.sectionTitle('不均匀网格先从比例开始', 'columnsTemplate 不一定都写 1fr。左边宽一点、右边窄一点,用 2fr 1fr 就能表达。')

          Grid() {
            GridItem() {
              Text('主入口')
                .width('100%')
                .height('100%')
                .fontSize(20)
                .fontWeight(700)
                .fontColor('#FFFFFF')
                .textAlign(TextAlign.Center)
                .backgroundColor('#2563EB')
                .borderRadius(8)
            }

            GridItem() {
              Text('状态')
                .width('100%')
                .height('100%')
                .fontSize(16)
                .fontWeight(700)
                .fontColor('#FFFFFF')
                .textAlign(TextAlign.Center)
                .backgroundColor('#0F766E')
                .borderRadius(8)
            }

            GridItem() {
              Text('工具')
                .width('100%')
                .height('100%')
                .fontSize(16)
                .fontWeight(700)
                .fontColor('#FFFFFF')
                .textAlign(TextAlign.Center)
                .backgroundColor('#C2410C')
                .borderRadius(8)
            }

            GridItem() {
              Text('更多')
                .width('100%')
                .height('100%')
                .fontSize(16)
                .fontWeight(700)
                .fontColor('#FFFFFF')
                .textAlign(TextAlign.Center)
                .backgroundColor('#7C3AED')
                .borderRadius(8)
            }
          }
          .width('100%')
          .height(190)
          .columnsTemplate('2fr 1fr')
          .rowsTemplate('1fr 1fr')
          .columnsGap(10)
          .rowsGap(10)
        }
        .width('100%')
        .padding(16)
        .backgroundColor('#F8FAFC')
        .borderRadius(8)
      }
      .width('100%')
      .padding(20)
      .alignItems(HorizontalAlign.Start)
    }
    .width('100%')
    .height('100%')
    .backgroundColor('#FFFFFF')
  }
}
【版权声明】本文为华为云社区用户原创内容,未经允许不得转载,如需转载请自行联系原作者进行授权。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。