尧图网站建设 尧图网络
  • 首页
  • 关于我们
  • 服务项目
  • 案例展示
  • 建站流程
  • 资讯中心
  • 联系我们
首页/资讯中心/详情

HarmonyOS ArkUI Grid 网格布局:固定列、自适应列与跨列 GridItem

HarmonyOS ArkUI Grid 网格布局:固定列、自适应列与跨列 GridItem
📅 发布时间:2026/7/21 3:19:44

系列:鸿蒙 HarmonyOS 6.1 新特性实战 · 第 48 篇

Grid 是 ArkUI 中专为二维网格场景设计的布局容器,配合 GridItem 使用,可以轻松实现商品列表、图片墙、仪表盘等经典界面。与 Column/Row 的一维排列不同,Grid 通过columnsTemplate和rowsTemplate精确定义每列每行的尺寸比例,并支持 GridItem 跨列/跨行占据多个格子。本篇通过商品网格与横幅跨列两个实战示例讲透 Grid 的核心用法。

运行效果

初始状态(2 列等宽商品网格):

切换为 3 列自适应模式,横幅 GridItem 横跨两列:

columnsTemplate 与 rowsGap/columnsGap

columnsTemplate是 Grid 的核心属性,使用空格分隔的 fr 单位字符串定义每一列的宽度比例,与 CSS Grid 的grid-template-columns一脉相承:

// 2 列等宽商品网格 Grid() { GridItem() { Column({ space: 8 }) { Text('🎧').fontSize(48) Text('无线耳机').fontSize(13).fontColor('#333') Text('¥299') .fontSize(14).fontColor('#e74c3c') .fontWeight(FontWeight.Bold) } .width('100%').padding(12) .backgroundColor('#fff').borderRadius(8) .alignItems(HorizontalAlign.Center) } GridItem() { Column({ space: 8 }) { Text('📱').fontSize(48) Text('智能手表').fontSize(13).fontColor('#333') Text('¥599') .fontSize(14).fontColor('#e74c3c') .fontWeight(FontWeight.Bold) } .width('100%').padding(12) .backgroundColor('#fff').borderRadius(8) .alignItems(HorizontalAlign.Center) } GridItem() { Column({ space: 8 }) { Text('💻').fontSize(48) Text('平板电脑').fontSize(13).fontColor('#333') Text('¥1299') .fontSize(14).fontColor('#e74c3c') .fontWeight(FontWeight.Bold) } .width('100%').padding(12) .backgroundColor('#fff').borderRadius(8) .alignItems(HorizontalAlign.Center) } GridItem() { Column({ space: 8 }) { Text('🎮').fontSize(48) Text('游戏手柄').fontSize(13).fontColor('#333') Text('¥199') .fontSize(14).fontColor('#e74c3c') .fontWeight(FontWeight.Bold) } .width('100%').padding(12) .backgroundColor('#fff').borderRadius(8) .alignItems(HorizontalAlign.Center) } } .columnsTemplate('1fr 1fr') // 2 列等宽 .columnsGap(12) // 列间距 12vp .rowsGap(12) // 行间距 12vp .width('100%') .backgroundColor('#f5f5f5') .padding(12)

'1fr 1fr'表示 2 列等宽;'1fr 2fr 1fr'表示 3 列,中间列是两侧列宽度的 2 倍;'120vp 1fr'表示左列固定 120vp,右列占满剩余空间。rowsTemplate同理控制行高,若省略则行高由内容决定(自动扩展)。

GridItem 跨列:columnStart 与 columnEnd

横幅、广告位等需要横跨多列的场景,通过 GridItem 的columnStart和columnEnd属性实现:

Grid() { // 横幅:跨越 0、1 两列(columnsTemplate 为 2 列时) GridItem() { Text('Banner 横幅——限时特惠') .width('100%').height(100) .backgroundColor('#0066ff').fontColor('#fff') .textAlign(TextAlign.Center).fontSize(16) .borderRadius(8) } .columnStart(0).columnEnd(1) // 0-indexed,inclusive,跨越第 0 和第 1 列 // 普通商品格子 GridItem() { Column({ space: 6 }) { Text('⌚').fontSize(36) Text('智能手表').fontSize(12).fontColor('#333') Text('¥399').fontSize(13).fontColor('#e74c3c').fontWeight(FontWeight.Bold) } .width('100%').padding(10).backgroundColor('#fff').borderRadius(8) .alignItems(HorizontalAlign.Center) } GridItem() { Column({ space: 6 }) { Text('🎵').fontSize(36) Text('蓝牙音箱').fontSize(12).fontColor('#333') Text('¥179').fontSize(13).fontColor('#e74c3c').fontWeight(FontWeight.Bold) } .width('100%').padding(10).backgroundColor('#fff').borderRadius(8) .alignItems(HorizontalAlign.Center) } } .columnsTemplate('1fr 1fr') .columnsGap(12).rowsGap(12) .width('100%').backgroundColor('#f5f5f5').padding(12)

columnStart和columnEnd均为 0 起始索引,且columnEnd包含该列(inclusive)。若columnsTemplate是'1fr 1fr 1fr'(3 列),则跨全行需设.columnStart(0).columnEnd(2)。rowStart和rowEnd可类比用于跨行。

Grid vs List:选型指南

两者在列表场景下经常被拿来比较:

// Grid:二维布局,适合商品网格、图片墙 Grid() { ForEach(products, (product: Product) => { GridItem() { ProductCard({ product: product }) } }) } .columnsTemplate('1fr 1fr') .columnsGap(12).rowsGap(12) .width('100%') // List:一维列表,适合消息列表、设置项 List({ space: 12 }) { ForEach(messages, (msg: Message) => { ListItem() { MessageRow({ msg: msg }) } }) } .width('100%')

Grid 适合二维场景:商品网格、图片墙、仪表盘卡片;List 适合一维场景:消息流、设置列表、时间轴。若需要高度不固定的瀑布流效果,应使用 WaterFlow(见第 49 篇)。

完整代码

class ProductItem { icon: string = '' name: string = '' price: string = '' } @Entry @Component struct GridDemo { @State colCount: number = 2 @State template: string = '1fr 1fr' private products: ProductItem[] = [ { icon: '🎧', name: '无线耳机', price: '¥299' }, { icon: '📱', name: '智能手表', price: '¥599' }, { icon: '💻', name: '平板电脑', price: '¥1299' }, { icon: '🎮', name: '游戏手柄', price: '¥199' }, { icon: '📷', name: '运动相机', price: '¥899' }, { icon: '🔊', name: '蓝牙音箱', price: '¥179' }, ] @Builder ProductCard(item: ProductItem) { Column({ space: 8 }) { Text(item.icon).fontSize(40) Text(item.name).fontSize(13).fontColor('#333') Text(item.price) .fontSize(14).fontColor('#e74c3c') .fontWeight(FontWeight.Bold) } .width('100%').padding(12) .backgroundColor('#fff').borderRadius(8) .alignItems(HorizontalAlign.Center) } build() { Column({ space: 16 }) { // 标题 Text('Grid 网格布局演示') .fontSize(16).fontWeight(FontWeight.Bold).fontColor('#1a1a1a') // 切换列数 Row({ space: 12 }) { Button('2 列').height(36) .backgroundColor(this.colCount === 2 ? '#0066ff' : '#e0e0e0') .fontColor(this.colCount === 2 ? '#fff' : '#333') .onClick(() => { this.colCount = 2 this.template = '1fr 1fr' }) Button('3 列').height(36) .backgroundColor(this.colCount === 3 ? '#0066ff' : '#e0e0e0') .fontColor(this.colCount === 3 ? '#fff' : '#333') .onClick(() => { this.colCount = 3 this.template = '1fr 1fr 1fr' }) } // Banner 跨列演示 Text('跨列 Banner + 商品网格') .fontSize(14).fontColor('#666') Grid() { // 横幅:跨全部列 GridItem() { Text('限时特惠 · 全场满 300 减 50') .width('100%').height(80) .backgroundColor('#0066ff').fontColor('#fff') .textAlign(TextAlign.Center).fontSize(15) .borderRadius(8) } .columnStart(0) .columnEnd(this.colCount - 1) // 商品列表 ForEach(this.products, (item: ProductItem) => { GridItem() { this.ProductCard(item) } }) } .columnsTemplate(this.template) .columnsGap(10).rowsGap(10) .width('100%') .backgroundColor('#f5f5f5').padding(10) } .width('100%').padding(16) .backgroundColor('#ffffff') } }

API 速查

属性/方法说明
.columnsTemplate(string)列宽模板,如'1fr 1fr'、'120vp 1fr',空格分隔
.rowsTemplate(string)行高模板,省略时行高由内容自动决定
.columnsGap(number)列间距,单位 vp
.rowsGap(number)行间距,单位 vp
GridItem.columnStart(number)跨列起始列索引(0 起始)
GridItem.columnEnd(number)跨列结束列索引(包含,0 起始)
GridItem.rowStart(number)跨行起始行索引
GridItem.rowEnd(number)跨行结束行索引(包含)

小结

  • columnsTemplate用 fr 单位字符串定义列数和列宽比例,是 Grid 布局的核心属性
  • columnsGap和rowsGap分别控制列间距和行间距,比 padding/margin 更语义化
  • columnStart/columnEnd实现跨列,索引从 0 开始且 columnEnd 为包含值
  • 省略rowsTemplate时行高由 GridItem 内容决定,适合高度不一致的商品卡片
  • 不要将自定义类或结构体命名为GridItem,会与 ArkUI 内置组件名冲突
  • Grid 适合二维网格;List 适合一维列表;高度不一致的瀑布流用 WaterFlow(第 49 篇)

上一篇:Flex 弹性布局完全指南 | 下一篇:WaterFlow 瀑布流布局实战

相关新闻

  • 生产级AI智能体架构设计与Rust实现
  • 2026年 重庆物流公司/物流专线推荐榜:干线运输与仓储配送一体化实力之选 - 甄选服务推荐
  • LangChain与LangGraph架构对比:状态机模型如何优化AI应用开发

最新新闻

  • 卖表避坑!钟表协会 2026 大连正规腕表回收名录,靠谱线下门店公示 - 日常财经早知道
  • 自制Linux开发板:全志V853开源方案与物联网应用
  • 英语作文_Learning to Be Yourself
  • 如何永久保存微信聊天记录:WeChatMsg完全指南让珍贵对话永不消失
  • NLP开发者必备!gh_mirrors/fi/finetune BaseModel类深度剖析与实战指南
  • 终极指南:5分钟快速搭建PostgreSQL版Northwind数据库

日新闻

  • Python开发内部工具:7大核心库实战解析
  • 合肥雷达官方2026年7月最新信息:客户服务网点地址与售后热线权威公示 - 亨得利官方服务中心
  • PCA实战指南:从变量纠缠诊断到主成分业务解读

周新闻

  • SaaS软件行业GEO实践:AI搜索时代的品牌可见性与获客新路径
  • 什么是PCTFE?医药高端包装的“防潮王牌“材料
  • 【JVM调优实战】16-可视化利器-JConsole-VisualVM-JMC

月新闻

  • 2026年6月公司网站搭建最新热门渠道测评:四大低成本/零代码平台对比+避坑
  • 【Linux】Linux arm 编译QT程序,出现expected “}“报错
  • 【MATLAB例程】四基站二维AOA定位与距离辅助增强对比仿真。基于角度观测和测距修正的固定目标平面定位精度分析

关于尧图

  • 公司简介
  • 团队介绍
  • 企业文化
  • 荣誉资质

服务项目

  • 定制开发
  • 电商建站
  • UI 设计
  • 运维服务

快速链接

  • 案例展示
  • 建站流程
  • 常见问题
  • 资讯中心

联系方式

  • 📍北京市朝阳区互联网产业园 A 座 10 层
  • 📞400-888-8888
  • ✉️contact@rkmt.cn
  • 🕐周一至周日 9:00-21:00

© 2024 北京尧图网络科技有限公司 版权所有 | 京 ICP 备 XXXXXXXX 号