news 2026/7/6 4:02:01

鸿蒙新特性:Grid 网格布局组件详解——构建动态照片画廊

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
鸿蒙新特性:Grid 网格布局组件详解——构建动态照片画廊

网格布局是移动端最经典的排版方式之一。从照片墙到应用抽屉,从商品列表到图标菜单,等分网格承载了大量信息展示任务。HarmonyOS NEXT ArkUI 提供了 Grid 组件,通过columnsTemplate属性灵活定义列数与列宽,配合GridItem渲染子元素,轻松实现各种网格效果。

本文将深入讲解 Grid 组件的核心 API,并通过一个"动态照片画廊"实战案例,展示列数切换、选中高亮和多选管理等功能。

关键词:HarmonyOS、ArkUI、Grid、网格布局、照片画廊、动态列数

一、Grid 组件概览

Grid 是 ArkUI 容器组件家族中专门用于网格布局的成员。与 List(线性列表)、WaterFlow(瀑布流)和 Scroll(自由滚动)相比,Grid 的核心特征在于等分列——所有子元素按固定的列数排列,行高一致,视觉整齐统一。

组件排列方式典型场景
List单列线性消息列表、设置选项
Grid多列等分照片墙、应用抽屉、图标菜单
WaterFlow多列不等高图片流、商品发现
Scroll自由排布内容页面

Grid 的优势在于"规整"——当你的内容需要以 N 列的方式整齐排列时,Grid 是最合适的选择。

二、Grid 核心 API

2.1 构造函数与列模板

Grid 的列定义通过columnsTemplate属性控制,使用类似 CSS Grid 的语法:

Grid(){ForEach(this.items,(item)=>{GridItem(){/* 内容 */}})}.columnsTemplate('1fr 1fr 1fr')// 3 等分列

columnsTemplate支持以下格式:

  • '1fr 1fr'— 2 等分列(每列占 50% 宽度)
  • '1fr 1fr 1fr'— 3 等分列(每列占 33.3% 宽度)
  • '1fr 1fr 1fr 1fr'— 4 等分列(每列占 25% 宽度)
  • '120vp 1fr'— 混合模式(第一列固定 120vp,第二列占剩余宽度)

frfraction unit(分数单位)的缩写,1fr表示"占 1 份可用空间"。如果有 3 个1fr,则每列各占 1/3 宽度。

2.2 间距控制

Grid(){...}.columnsGap(8)// 列间距.rowsGap(8)// 行间距

列间距和行间距独立控制,通常设为相同值以保持视觉统一。

2.3 动态构建列模板

在实际项目中,列数往往需要根据用户偏好动态调整。由于columnsTemplate接受字符串,我们可以动态构建:

buildTemplate(cols:number):string{lett='1fr';for(leti=1;i<cols;i++){t=t.concat(' 1fr');}returnt;}// 使用:Grid(){...}.columnsTemplate(this.buildTemplate(this.colCount))

colCount变化时,columnsTemplate字符串更新,Grid 自动重新排版。

2.4 GridItem

每个网格单元必须包裹在GridItem()中:

ForEach(this.photos,(photo:PhotoItem)=>{GridItem(){Column(){Text(photo.emoji).fontSize(32)Text(photo.label).fontSize(13)}.width('100%').height('100%').justifyContent(FlexAlign.Center).backgroundColor(photo.color).borderRadius(12)}})

GridItem提供了网格布局所需的尺寸测量能力,确保每列的子元素对齐。

三、实战:动态照片画廊

我们构建一个照片画廊,包含 18 张主题卡片(日出、海洋、森林、极光…),支持三种列数切换(2/3/4 列)和多选管理。

3.1 数据模型

每张"照片"用一个包含主题名、emoji 图标、背景色和文字色的对象表示:

interfacePhotoItem{id:number;label:string;// 主题名emoji:string;// emoji 图标color:string;// 背景色textColor:string;// 文字颜色(深色背景用白,浅色背景用黑)}aboutToAppear():void{this.photos=[{id:0,label:'日出',emoji:'🌅',color:'#FF6B6B',textColor:'#FFFFFF'},{id:1,label:'海洋',emoji:'🌊',color:'#4ECDC4',textColor:'#FFFFFF'},{id:2,label:'森林',emoji:'🌲',color:'#2ECC71',textColor:'#FFFFFF'},{id:3,label:'晚霞',emoji:'🌇',color:'#FF8C42',textColor:'#FFFFFF'},{id:4,label:'星空',emoji:'✨',color:'#6C5CE7',textColor:'#FFFFFF'},// ... 共 18 张];}

每张卡片使用独立的颜色方案(18 色),确保网格在任何列数下都呈现出丰富的色彩对比。

3.2 列数切换

三个触摸按钮——2 列、3 列、4 列——点击时切换colCount并清除当前选择:

ForEach([2,3,4],(n:number)=>{Text(n.toString().concat('列')).fontSize(13).fontColor(this.colCount===n?'#FFFFFF':'#666677').fontWeight(this.colCount===n?FontWeight.Bold:FontWeight.Normal).padding({top:6,bottom:6,left:12,right:12}).borderRadius(12).backgroundColor(this.colCount===n?'#1677FF':'#F2F3F5').margin({left:6}).onClick(()=>{this.colCount=n;this.clearSelection();// 切换列数时重置选择})},(n:number)=>n.toString())

切换列数时清除选中状态是一个重要的 UX 细节——因为列数变化会导致卡片位置重新排列,保留旧选中状态会让用户困惑。

3.3 选中交互

点击卡片触发选中/取消,选中的卡片显示白色边框和扩展阴影:

toggleSelect(id:number):void{constfound=this.selectedIds.indexOf(id);if(found===-1){this.selectedIds.push(id);}else{this.selectedIds.splice(found,1);}}

每张卡片根据是否被选中动态调整样式:

.border({width:this.selectedIds.indexOf(photo.id)!==-1?3:0,color:'#FFFFFF',style:BorderStyle.Solid}).shadow(this.selectedIds.indexOf(photo.id)!==-1?{radius:12,color:photo.color.concat('88'),offsetX:0,offsetY:4}:{radius:4,color:'#00000012',offsetX:0,offsetY:2})

选中状态的双重视觉反馈:

  1. 白色边框(3vp 宽):清晰标识哪些卡片被选中
  2. 彩色扩展阴影(12vp 半径):使用卡片自身的颜色 + 半透明(88),产生"发光"效果

非选中状态的阴影则较轻(4vp 半径、浅黑半透明),保持卡片的层次感但不抢夺注意力。

3.4 选择计数与清除

在列数切换器右侧显示已选数量和清除入口:

if(this.selectedIds.length>0){Row(){Text('已选 '.concat(this.selectedIds.length.toString())).fontSize(12).fontColor('#1677FF').fontWeight(FontWeight.Medium)Text(' | 清除').fontSize(12).fontColor('#FF4D4F').onClick(()=>{this.clearSelection();})}}

这个信息区域仅在选中至少 1 张卡片后才显示,保持界面的简洁。清除按钮使用红色(#FF4D4F)暗示其"清空"的操作性质。

四、Grid vs List vs WaterFlow

选择哪个布局容器取决于内容特征:

特征GridListWaterFlow
内容高度统一可变可变
列数自定义1自定义
列对齐强制对齐紧凑排列
适用图标菜单、相册消息、设置图片流

如果你的内容卡片的宽高比一致(如本例中的 18 张主题卡片),Grid 是天然的选择。如果内容高度差异大(如不同长度的文字卡片),WaterFlow 更合适。如果只需要单列,List 最简单。

五、完整交互流程

  1. 初始状态:进入页面,3 列网格展示 18 张彩色主题卡片,无任何选中
  2. 切换列数:点击"2 列"按钮,卡片重新排版为 2 列;点击"4 列",变为 4 列
  3. 选中卡片:点击"星空"卡片,出现白色边框 + 紫色发光阴影,右上角显示"已选 1 | 清除"
  4. 多选:继续点击"海洋"和"日出",已选计数变为 3,三张卡片同时高亮
  5. 取消选中:再次点击"星空",计数变为 2,该卡片恢复默认样式
  6. 清除选择:点击"清除",所有选中状态归零,计数信息消失

六、总结

Grid 是 ArkUI 中设计最简洁的布局组件之一。它的核心就是一条属性:columnsTemplate。掌握了这个属性的用法,就能在 2 列、3 列、4 列甚至混合列宽之间自由切换。

本文通过"照片画廊"这个实战案例,覆盖了:

  1. columnsTemplate的动态构建与列数切换
  2. GridItem 的嵌套使用
  3. 选中状态的边框 + 阴影双重反馈
  4. 多选管理与计数清除
  5. Grid / List / WaterFlow 的选择原则

Grid 配合 List(列表)、WaterFlow(瀑布流)和 Scroll(滚动),构成了 ArkUI 布局体系的四大容器。根据内容特征选择合适的容器,是鸿蒙应用 UI 开发的基础能力。


版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/6 4:00:50

:NLP任务的首次大一统

把分类、摘要、问答、翻译等一切 NLP 任务都塞进一个框架里&#xff1a;输入是文本&#xff0c;输出也是文本。 从地位和后续影响来说&#xff0c;T5 可以说是现代自然语言指令对话的起点&#xff0c;是对 NLP 任务形式的首次大一统&#xff0c;因此&#xff0c;本篇同样先展开…

作者头像 李华
网站建设 2026/7/6 3:58:52

告别鼠标手:3步掌握AutoClicker自动化点击工具

告别鼠标手&#xff1a;3步掌握AutoClicker自动化点击工具 【免费下载链接】AutoClicker AutoClicker is a useful simple tool for automating mouse clicks. 项目地址: https://gitcode.com/gh_mirrors/au/AutoClicker 你是否曾在深夜加班时&#xff0c;手指因为重复点…

作者头像 李华
网站建设 2026/7/6 3:58:10

【mp4文件的图标在文件夹中显示视频第一帧】

需求&#xff1a;视频文件显示第一帧而不是视频图标。 方案&#xff1a;使用软件 media previw&#xff0c;用于恢复Windows资源管理器中不支持或损坏的媒体文件类型的缩略图预览。它允许用户预览视频文件的图片预览&#xff0c;否则这些文件通常只显示默认图标

作者头像 李华
网站建设 2026/7/6 3:58:06

ASP.NET MVC实践系列9-filter原理与实践

我们先来看看ASP.NET MVC 框架提供的几种默认filter类型: 1、Authorize&#xff1a; 准备工作&#xff1a;进入C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727文件夹&#xff0c;双击aspnet_regsql.exe选择好相应的数据库&#xff0c;创建membership&#xff0c;AuthorizeAtt…

作者头像 李华
网站建设 2026/7/6 3:57:12

PowerShell 路径规则详解:从基础到高级

1. 引言在 Windows 系统管理和自动化脚本编写中&#xff0c;PowerShell 是功能强大的工具。无论是访问文件、加载模块&#xff0c;还是执行脚本&#xff0c;都离不开对路径的正确理解和处理。PowerShell 的路径规则与传统的 CMD 有所不同&#xff0c;它更灵活&#xff0c;但也更…

作者头像 李华
网站建设 2026/7/6 3:56:47

126、DyHead 动态检测头替换 YOLOv11 Head:Scale+Space+Task 三维注意力的实现

126、DyHead 动态检测头替换 YOLOv11 Head:Scale+Space+Task 三维注意力的实现 从一次诡异的mAP抖动说起 去年年底调YOLOv11的C2f模块,发现一个奇怪现象:换了几种注意力机制,mAP@0.5:0.95始终在0.523附近震荡,死活上不去。后来扒开特征图一看,深层小目标特征被背景噪声…

作者头像 李华