鸿蒙 Grid 与 GridItem 深度解析:二维网格布局解决方案

一、引言:网格布局 —— 多维度数据展示的黄金方案

在鸿蒙应用开发体系中,网格布局作为处理多元素有序排列的核心方案,广泛应用于电商商品陈列、图片画廊、功能矩阵等场景。鸿蒙提供的 Grid 与 GridItem 组件通过声明式语法构建灵活的二维布局系统,支持行列比例分配、单元格合并、滚动交互等高级特性,相比传统线性布局可提升 30% 的复杂界面开发效率。本文将系统解析这组黄金搭档的核心机制与工程实践,帮助开发者掌握多维度数据可视化的鸿蒙解法。

二、核心架构:Grid 与 GridItem 的协作模型

2.1 组件定位与层级关系

  • Grid:网格容器组件,负责定义行列结构、间距规则、滚动方向等全局布局参数
  • GridItem:网格项组件,作为 Grid 的直接子组件,支持单元格跨行列合并与个性化配置

典型层级结构示意图:

Grid (网格容器)
├─ GridItem (占据第1行第1列)
├─ GridItem (占据第1行第2-3列)
└─ GridItem (占据第2-3行第1列)

2.2 核心技术优势

  • 响应式布局:通过fr弹性单位实现屏幕自适应,适配手机 / 平板 / 车机等多端设备
  • 灵活布局能力:支持单元格跨越多行多列,满足日历、计算器等复杂布局需求
  • 高性能渲染:结合 LazyForEach 实现大数据量懒加载,列表渲染性能提升 50%

三、Grid 核心属性:构建网格骨架

3.1 行列结构配置

行列模板定义

通过rowsTemplate/columnsTemplate声明行列比例,支持 fr 弹性单位与固定值混合使用:

Grid().rowsTemplate('80vp 1fr')      // 首行固定80vp,次行弹性填充.columnsTemplate('1fr 2fr 1fr') // 三列按1:2:1比例分配.rowsGap(12)                   // 行间距12vp.columnsGap(16)                // 列间距16vp
fr 单位计算逻辑
  • 1fr 表示 1 份弹性空间,总份数由声明的 fr 数量决定
  • 示例:columnsTemplate('1fr 2fr')表示两列宽度比为 1:2

3.2 滚动与布局控制

水平滚动网格
Grid().rowsTemplate('1fr')            // 单行布局.columnsTemplate('1fr 1fr 1fr') // 三列结构.height(200)                    // 固定高度触发水平滚动.scrollBar(BarState.Auto)       // 自动显示滚动条
垂直滚动网格
Grid().columnsTemplate('1fr')          // 单列布局.rowsTemplate('1fr 1fr 1fr')     // 三行结构.width(300)                     // 固定宽度触发垂直滚动.edgeEffect(EdgeEffect.Spring)   // 边缘弹性效果
流式布局模式

未设置行列模板时,通过layoutDirection控制排列方向:

Grid().layoutDirection(GridDirection.Row) // 水平排列(默认).maxCount(4)                       // 每行最多4个单元格

四、GridItem 核心属性:单元格个性化定制

4.1 跨行列合并

通过rowStart/rowEndcolumnStart/columnEnd定义单元格占据范围(行列号从 1 开始):

GridItem().columnStart(1)    // 起始列1.columnEnd(3)      // 结束列3(占据2列).rowStart(2)       // 起始行2.rowEnd(4)         // 结束行4(占据3行)

实战案例:计算器按键布局

GridItem() { Text('0') }.columnStart(1).columnEnd(3)      // 占据2列宽度

4.2 性能优化控制

通过forceRebuild控制组件重建时机:

GridItem().forceRebuild(false) // 禁止随父组件重建(适用于静态内容)

设置在触发组件build时是否重新创建此节点。GridItem会根据自身属性和子组件变化自行决定是否需要重新创建,无需设置。 

五、实战案例:从基础到复杂的网格开发

5.1 基础九宫格图片墙

@Entry
@Component
struct ImageGrid {private images: string[] = Array(9).map((i:number) => `img_${i + 1}`);build() {Grid() {ForEach(this.images, (img:string) => {GridItem() {Image(img).width('100%').height('100%').objectFit(ImageFit.Cover).borderRadius(8)}})}.rowsTemplate('1fr 1fr 1fr').columnsTemplate('1fr 1fr 1fr').rowsGap(10).columnsGap(10).width('100%').height(300)}
}

5.2 水平滚动商品列表

interface Product {id: number;name: string;price: number;image: string;
}@Entry
@Component
struct ProductGrid {// 显式声明数组类型并初始化private products: Product[] = [{ id: 1, name: "商品1", price: 99, image: "img1" },{ id: 2, name: "商品2", price: 199, image: "img2" }// 实际项目应通过API获取数据];build() {Grid() {// 显式声明LazyForEach参数类型LazyForEach(this.products, //这里需要DataSource类型,而不是Product[] 我偷点懒直接用了(item: Product) => {GridItem() {ProductCard({ productData: item }) // 传递显式类型参数}.width('25%')},(item: Product) => item.id.toString() // 确保key为string类型)}.rowsTemplate('1fr').height(200).columnsGap(12).width('100%').cachedCount(5)}
}// 商品卡片组件需明确定义props类型
@Component
struct ProductCard {@ObjectLink productData: Product; // 使用ObjectLink监听对象变化build() {Column() {Image(this.productData.image).width(80).height(80)Text(this.productData.name).fontSize(14)Text(`¥${this.productData.price.toFixed(2)}`).fontColor(Color.Red)}.padding(10)}
}

5.3 复杂日历布局

    Grid() {// 标题行(跨全列)GridItem() { Text('2023年12月') }.columnStart(1).columnEnd(8) // 7列+1边距// 星期标题ForEach(['日', '一', '二', '三', '四', '五', '六'], (title, idx) => {GridItem() { Text(title) }.width('14.28%') // 7列均分})// 日期单元格(周末跨2列)ForEach(this.calendarData, (date:CalendarData) => {GridItem() { Text(date.day) }.width(date.isWeekend ? '28.56%' : '14.28%') // 周末占2列})}.columnsTemplate('1fr 1fr 1fr 1fr 1fr 1fr 1fr') // 7列结构

六、工程实践最佳指南

6.1 性能优化策略

大数据量懒加载
Grid() {LazyForEach(largeData, (item) => GridItem(), item => item.id)
}
.cachedCount(8) // 预加载当前显示项前后各8个
.useVirtualized(true) // 启用虚拟列表(API 10+)
复杂布局优化
  • 避免超过 3 层的网格嵌套
  • 固定高度 / 宽度的网格项使用.itemSize()声明,提升布局计算效率

6.2 多端适配方案

#if (DeviceType == DeviceType.Phone)Grid().columnsTemplate('1fr 1fr') // 手机端2列
#elif (DeviceType == DeviceType.Tablet)Grid().columnsTemplate('1fr 1fr 1fr') // 平板端3列
#elif (DeviceType == DeviceType.Desktop)Grid().columnsTemplate('1fr 1fr 1fr 1fr') // 桌面端4列
#endif

6.3 常见问题解决方案

问题场景解决方案
单元格溢出检查 GridItem 是否设置width/height: 100%,并通过maxWidth/maxHeight限制
滚动失效确认仅设置单行 / 单列模板,且内容超出容器尺寸,可添加.scrollBar(BarState.Always)强制显示
合并错乱确保rowEnd/columnEnd不超过 Grid 的行列总数,行列号从 1 开始计数
性能卡顿大数据量场景使用LazyForEach+cachedCount,避免使用ForEach直接渲染

七、总结:网格布局的全场景应用

鸿蒙 Grid 与 GridItem 组件通过声明式语法将复杂二维布局转化为结构化配置,核心能力包括:

  1. Grid 容器:行列模板定义、间距控制、滚动管理
  2. GridItem 项:跨行列合并、性能优化控制
  3. 工程实践:懒加载、多端适配、性能调优

在实际开发中,建议遵循 "先结构后细节" 的开发流程:先通过 Grid 定义行列骨架,再通过 GridItem 实现单元格个性化。随着鸿蒙生态向全场景设备拓展,网格布局在大屏设备(如平板、智慧屏)上的优势将更加显著,开发者可结合官方模拟器的多设备预览功能,打造适配全场景的网格界面。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/web/86612.shtml
繁体地址,请注明出处:http://hk.pswp.cn/web/86612.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

​​Vue 开发环境配置:使用 devServer.proxy 解决跨域问题​-vue中文件vue.config,js中配置devserver做反向代理到后端

​​Vue 开发环境配置:使用 devServer.proxy 解决跨域问题​​ ​​引言​​ 在现代 Web 开发中,前端和后端通常独立开发,前端运行在 http://localhost:8080,而后端可能运行在 http://localhost:8000 或其他端口。由于浏览器的 …

JVM 中的 GC 算法演进之路!(Serial、CMS、G1 到 ZGC)

引言 想象一下,Java 程序运行就像在一个巨大的图书馆里借书还书。这个图书馆(JVM 的内存堆区)为了高效运转,需要一个聪明的“图书管理员”来清理失效的书籍(垃圾对象)。这,就是垃圾回收器&#…

(9)python+playwright自动化测试-页面(page)

1.简介 通过前边的讲解和学习,细心认真地你可能发现在Playwright中,没有Element这个概念,只有Page的概念,Page不仅仅指的是某个页面,例如页面间的跳转等,还包含了所有元素、事件的概念,所以我们…

《自动控制原理 》- 第 1 章 自动控制的基本原理与方式

1-1 自动控制的基本原理与方式 自动控制是指在没有人直接参与的情况下,利用外加的设备或装置,使机器、设备或生产过程的某个工作状态或参数按照预定的规律运行。自动控制的核心原理是反馈控制,即通过将系统的输出量回送到输入端,与…

DL00715-基于YOLOv11的水面漂浮物目标检测含数据集

【论文必备】基于YOLOv11的水面漂浮物目标检测——让你的研究走在科技前沿! 在环境监测、海洋保护和水质管理领域,水面漂浮物的检测一直是一个亟待解决的难题。传统的人工巡检方式不仅耗时费力,还无法覆盖广泛的水域范围。如今,基…

权电阻网络DAC实现电压输出型数模转换Multisim电路仿真——硬件工程师笔记

目录 1 基础知识 1.1 运算放大器在DAC中的作用 1.2 常见的基于运算放大器的DAC电路 1.2.1 倒T形电阻网络DAC 1.2.2 权电阻网络DAC 1.2.3 开关电容DAC 1.3 运算放大器的选择 1.4 设计注意事项 2 仿真实验 2.1 权电阻网络DAC实现数字0对应电压输出 2.2 权电阻网络DAC实…

Redis主从集群

✅ 一、什么是 Redis 主从集群? Redis 主从(Master-Slave)集群是一种最基础的集群方式: 一台 Redis 作为主节点(Master),负责写操作; 一到多台 Redis 作为从节点(Slave&…

【水印论文阅读1】将水印规则的定义域从离散的符号空间转移到连续的语义空间

【水印论文阅读1】将水印规则的定义域从离散的符号空间转移到连续的语义空间 写在最前面**为什么“token序列空间”有根本缺陷?****为什么“语义向量空间”能破局?****1. 连续性(抗攻击的核心)****2. 高维复杂性(防破解…

Glide缓存机制

一、缓存层级与设计目标 双级缓存: 内存缓存:弱引用 LruCache 磁盘缓存:DiskLruCache 设计目标: 减少网络流量消耗 避免Bitmap频繁创建/销毁引发的GC 提升图片加载速度 二、内存缓存机制 1. 双缓存结构 缓存类型存储对象…

BaiduSitemap - Typecho站点地图生成与多搜索引擎推送插件

文章目录 🌐 BaiduSitemap - Typecho站点地图生成与多搜索引擎推送插件✨ 功能特点🧩 插件架构核心模块文件结构📦 安装方法方法一:手动安装方法二:Git克隆⚙️ 配置说明站点地图基本设置搜索引擎配置百度搜索引擎必应(Bing)搜索引擎谷歌(Google)搜索引擎🚀 使用…

androidx中<layout>根布局的意义及用法

在 Android 开发中,<layout> 根布局是 Android Jetpack Data Binding 库的核心组件,用于声明该 XML 布局文件将使用数据绑定功能。以下是详细说明: 📌 一、基本作用 1. 启用数据绑定 <layout> 标签标志着此布局文件支持数据绑定,编译器会为其生成对应的绑定类…

QTreeWidget 简单使用

效果图&#xff1a; 关键代码&#xff1a; void MainProj::_InitTree() { connect(m_pTreeWidget, SIGNAL(itemClicked(QTreeWidgetItem*, int)), this, SLOT(TreeItemClicked(QTreeWidgetItem*, int))); m_pTreeWidget->header()->setHidden(1); /*QTreeWid…

手势-handpose的pipeline介绍

手势-handpose的pipeline包括&#xff1a; 1、手部检测算法&#xff1a;单帧检测出左右手的边界框。 2、手部跟踪算法&#xff1a;连续帧跟踪&#xff0c;锁定左右手跟踪目标&#xff0c;作为后续的手部ui操作。 3、手部关键点检测算法&#xff1a;基于单帧的检测框图像作为输…

计算机操作系统(十七)内存管理

计算机操作系统&#xff08;十七&#xff09;内存管理 前言一、内存的使用与程序重定位&#xff08;一&#xff09;内存是什么&#xff1f;&#xff08;二&#xff09;程序的重定位过程&#xff08;三&#xff09;总结&#xff1a;内存使用的核心问题 二、连续分区管理&#xf…

【编译原理】期末

单选题 (4分) 令文法G[E]为&#xff1a;E->ET | T T->T*F | F F-> (E) | i 句型 F*iT 的最左素短语是&#xff08; &#xff09; A.F B.i C.T D.F*i B 短语&#xff1a; F*iT、F*i、F、i 素短语&#xff1a; i 最左素短语&#xff1a; i 单选题 (4分) 若在…

一个简单测试Deepseek吞吐量的脚本,国内环境可跑

一个简单测试Deepseek吞吐量的脚本,这里用DeepSeek-R1-Distill-Qwen-32B ,支持单卡4090 24G可跑,具体看你的硬件情况做调整,理论支持所有的模型,看你需要,可以修改模型名称,重点是pip使用国内的源,模型下载用阿里的ModelScope,无障碍下载,使用. 最后可以生成一个txt与html报表.…

前端基础知识JavaScript系列 - 19(正则表达式)

一、是什么 正则表达式是一种用来匹配字符串的强有力的武器 它的设计思想是用一种描述性的语言定义一个规则&#xff0c;凡是符合规则的字符串&#xff0c;我们就认为它“匹配”了&#xff0c;否则&#xff0c;该字符串就是不合法的 在 JavaScript中&#xff0c;正则表达式也…

Java锁机制知识点

一、锁的基础概念 1.1 什么是锁 在并发编程中&#xff0c;锁是用于控制多个线程对共享资源进行访问的机制。锁可以保证在同一时刻最多只有一个线程访问共享资源&#xff0c;从而保证数据的一致性。 1.2 锁的分类 可重入锁 vs 不可重入锁&#xff1a;可重入锁允许同一个线程…

2025下半年软考软件设计师(中级)怎么高效备考,目标是稳过线!

25下半年软考开始进入备考阶段&#xff0c;现在咱们就抛开那些文绉绉的官话&#xff0c;用大白话来聊聊2025下半年软考软件设计师&#xff08;中级&#xff09;怎么高效备考&#xff0c;目标是稳过线&#xff01; 核心思想&#xff1a;抓大放小&#xff0c;真题为王&#xff0…

Jupyter常见操作(持续更新)

Jupyter常见操作&#xff08;持续更新&#xff09; 本文主要整理一些常见的或者比较简单的Jupyter操作&#xff0c;尽量保证一次性整理出来&#xff0c;方便需要但是忘记的情况下可以直接查&#xff0c;希望能当字典。 1.查看Jupyter内核 jupyter kernelspec list 2.使用指定…