HarmonyOS应用开发实战:猫猫大作战-`ForEach` 的双层嵌套、`keyGenerator` 密钥、`width` 百分比响应式格子
前言「猫猫大作战」的棋盘是 5 行 × 8 列网格——40 个格子。如果手写 40 个Stack组件代码又长又难维护。ArkUI 的ForEach循环渲染就是为这类「重复结构 数据驱动」场景准备的——双层ForEach嵌套外层渲染行、内层渲染列几十行代码搞定 40 格。本篇以「猫猫大作战」游戏页棋盘背景网格为锚点把ForEach的双层嵌套、keyGenerator密钥、width百分比响应式格子讲透。读完本篇你将能独立写出双层 ForEach 棋盘、响应式格子尺寸、数据驱动列表渲染三种实战套路。提示本系列不讲 ArkTS 基础语法与环境搭建假设你已跟完第 1–12 篇。一、场景拆解棋盘 5×8 网格打开entry/src/main/ets/pages/Index.ets的GameView// 来源entry/src/main/ets/pages/Index.ets GameView() 第 1 层 Column() { ForEach([0, 1, 2, 3, 4], (row: number) { Row() { ForEach([0, 1, 2, 3, 4, 1, 2, 3], (col: number) { Stack() { Text().fontSize(20) } .width(${100 / COLS}%).height(${100 / ROWS}%) .backgroundColor((row col) % 2 0 ? #F0F4F8 : #E6EDF3) }, (col: number) col-${row}-${col}) } .width(100%).height(${100 / ROWS}%) }, (row: number) row-${row}) } .width(100%).height(100%)棋盘规格拆解维度取值作用行数ROWS 5外层 ForEach[0,1,2,3,4]列数COLS 8内层 ForEach[0,1,2,3,4,1,2,3]格宽${100/8}%12.5%每列 1/8 屏宽格高${100/5}%20%每行 1/5 棋盘高棋盘色(rowcol)%2 0 ? #F0F4F8 : #E6EDF3隔行变色关键观察内层 ForEach 的列数组[0,1,2,3,4,1,2,3]有重复值两个 1、两个 2、两个 3——这是项目早期 bug正确应该是[0,1,2,3,4,5,6,7]。后文会讲这种重复值如何让keyGenerator失效。二、ForEach 核心语法速览参考 ForEach 循环渲染官方指南。ForEach( arr: Array, // 数据数组 (item: T, index?: number) { // 渲染每个项的 Builder // UI 结构 }, (item: T, index?: number) string // keyGenerator 生成唯一密钥 )2.1 三个参数参数作用必填arr数据数组✅itemBuilder渲染每项的箭头函数✅keyGenerator生成唯一密钥的箭头函数⚠ 强烈推荐2.2 keyGenerator 的作用ForEach([1, 2, 3], (item: number) { Text(${item}) }, (item: number) key-${item}) // 密钥 key-1/key-2/key-3keyGenerator给每个渲染项生成唯一字符串密钥ArkUI 用它做diff 追踪——数据变化时只重建密钥变化的项其余复用。不写 keyGenerator 的后果ArkUI 用 index 做密钥数组中间插入/删除时所有项重建因为 index 全变了性能崩。2.3 唯一性铁律// ✅ 密钥唯一 (arr: [1, 2, 3], key: k-${item}) → k-1/k-2/k-3 // ❌ 密钥冲突arr 有重复值 (arr: [1, 2, 2, 3], key: k-${item}) → k-1/k-2/k-2/k-3 ← k-2 冲突冲突后果ArkUI 只渲染第一个k-2第二个被丢弃——重复值不显示。三、双层 ForEach 嵌套结构3.1 外层渲染行Column() { ForEach([0, 1, 2, 3, 4], (row: number) { Row() { /* 内层渲染列 */ } .width(100%).height(${100 / ROWS}%) }, (row: number) row-${row}) } .width(100%).height(100%)外层Column行自上而下排列。每行Row列自左而右排列高度${100/5}% 20%。密钥row-${row}→row-0/row-1/row-2/row-3/row-4唯一。3.2 内层渲染列Row() { ForEach([0, 1, 2, 3, 4, 1, 2, 3], (col: number) { Stack() { Text().fontSize(20) } .width(${100 / COLS}%).height(${100 / ROWS}%) .backgroundColor((row col) % 2 0 ? #F0F4F8 : #E6EDF3) }, (col: number) col-${row}-${col}) } .width(100%).height(${100 / ROWS}%)每格Stack宽${100/8}% 12.5%高${100/5}% 20%。密钥col-${row}-${col}→col-0-0/col-0-1/…带行号防跨行冲突。背景色(rowcol)%2隔行变色。3.3 密钥带行号的关键设计(row: number) col-${row}-${col} // 注意模板字符串里的 ${row}为什么不写col-${col}因为跨行会有同列号第 0 行第 1 列col-1第 1 行第 1 列col-1← 冲突带${row}后第 0 行第 1 列col-0-1第 1 行第 1 列col-1-1← 唯一双层 ForEach 密钥规则内层密钥必须包含外层变量否则跨行同列号冲突。四、width 百分比的响应式格子.width(${100 / COLS}%) // 12.5%4.1 模板字符串算百分比${100 / COLS}% // COLS8 → 12.5%关键模板字符串内可以做算术${100/8}%→12.5%。这样改COLS常量格子宽度自动响应。4.2 vs 固定 vp 尺寸// 方式 1百分比响应式本项目 .width(${100 / COLS}%) // 方式 2固定 vp不响应屏宽 .width(48) // 每格固定 48vp百分比的优势屏宽变化格子自动缩放5 寸屏和 7 寸屏都适配。固定 vp 的优势格子大小一致棋盘宽度随屏宽变化屏宽则棋盘宽。实战经验棋盘要齔屏用百分比棋盘要居中固定尺寸用 vp。本项目棋盘齔屏用百分比。4.3 height 百分比的同理.height(${100 / ROWS}%) // 20%每行高度${100/5}% 20%5 行正好齔满棋盘高。五、隔行变色的模运算.backgroundColor((row col) % 2 0 ? #F0F4F8 : #E6EDF3)5.1(row col) % 2的棋盘色逻辑(row col) % 2 0 // 偶数格 → 浅色 #F0F4F8 (row col) % 2 1 // 奇数格 → 深色 #E6EDF3棋盘色分布示意5×8行\列012345670浅深浅深浅深浅深1深浅深浅深浅深浅2浅深浅深浅深浅深3深浅深浅深浅深浅4浅深浅深浅深浅深关键(rowcol)%2让相邻格永远异色——经典棋盘视觉。5.2 vsrow % 2的行间变色// 方式 1棋盘格本项目 (row col) % 2 // 相邻格异色 // 方式 2行间变色 row % 2 // 相邻行异色同行同色差异棋盘格每格都是独立色块视觉精致。行间变色同行 8 格同色视觉更朴素。实战经验棋盘类游戏用(rowcol)%2列表类用row%2。六、内层数组重复值 bug 修正项目源码内层数组ForEach([0, 1, 2, 3, 4, 1, 2, 3], (col: number) { // ... }, (col: number) col-${row}-${col})问题数组[0,1,2,3,4,1,2,3]有重复值两个 1、两个 2、两个 3共 8 个元素但值范围 0–4。密钥冲突第 5 个元素值 1col-${row}-1第 7 个元素值 1col-${row}-1← 与第 5 个冲突后果第 5、7 个格子都值 1只渲染一个另一个被丢弃——棋盘少 3 个格子。6.1 修正用 0–7 唯一值// ✅ 正确8 个唯一值 ForEach([0, 1, 2, 3, 4, 5, 6, 7], (col: number) { // ... }, (col: number) col-${row}-${col})6.2 或用 Array.from 生成const COLS 8 const colArr: number[] Array.from({ length: COLS }, (_, i) i) // [0,1,2,3,4,5,6,7] ForEach(colArr, (col: number) { // ... }, (col: number) col-${row}-${col})关键教训ForEach 数组的值必须唯一如果 keyGenerator 用值生成密钥否则密钥冲突丢项。七、完整代码棋盘背景网格修正版const ROWS 5 const COLS 8 const colArr: number[] Array.from({ length: COLS }, (_, i) i) Builder GameView() { Stack() { // 第 1 层棋盘背景 Column() { ForEach([0, 1, 2, 3, 4], (row: number) { Row() { ForEach(colArr, (col: number) { Stack() { Text().fontSize(20) } .width(${100 / COLS}%).height(${100 / ROWS}%) .backgroundColor((row col) % 2 0 ? #F0F4F8 : #E6EDF3) }, (col: number) col-${row}-${col}) } .width(100%).height(${100 / ROWS}%) }, (row: number) row-${row}) } .width(100%).height(100%).zIndex(0) // 第 2 层猫咪层下篇讲 // 第 3 层顶部 HUD第 11 篇讲 } .width(100%).height(100%) .alignContent(Alignment.Top) }八、ForEach vs LazyForEach 取舍维度ForEachLazyForEach渲染时机全量立即渲染按需懒渲染数据规模小 100 项大≥ 100 项接口arr: ArrayIDataSource适用棋盘、固定网格、短列表长列表、聊天记录、动态数据实战经验棋盘 40 格用ForEach——数据量小全量渲染更简单。聊天 1000 条用LazyForEach——只渲染可见项省内存。本系列第 68 篇会专讲LazyForEach。九、调试技巧ForEach 怎么调console.info打数据Builder 里加console.info(render cell, row, col)看渲染次数。密钥唯一性验证console.info(key,col-{row}-{col})打所有密钥查重复。加临时 border给 Stack 加.border({ width: 1, color: Color.Red })看清格子边界。真机看棋盘色预览器渲染接近真机但隔行变色可能因屏密度差异以真机为准。十、性能与最佳实践keyGenerator 必写不写用 index 做密钥数组中间插删时全重建。密钥必须唯一数据有重复值时密钥加 index 后缀key-${item}-${index}。双层密钥带外层变量col-${row}-${col}防跨行同列号冲突。小数据用 ForEach大数据用 LazyForEach40 格用 ForEach1000 条用 LazyForEach。总结本篇我们从棋盘背景网格切入掌握ForEach的双层嵌套、keyGenerator唯一密钥、width百分比响应式格子、(rowcol)%2隔行变色四大要点并修正了项目源码内层数组重复值的 bug。核心要点ForEach 密钥必写且唯一双层密钥带外层变量百分比格子响应式小数据用 ForEach 大数据用 LazyForEach。下一篇我们将继续游戏页拆解棋盘隔行变色的模运算条件样式。如果这篇文章对你有帮助欢迎点赞、收藏⭐、关注你的支持是我持续创作的动力相关资源「猫猫大作战」项目源码本仓库entry/src/main/ets/pages/Index.etsForEach 循环渲染官方指南循环渲染 (ForEach) API 参考线性布局 (Row/Column) 官方指南开源鸿蒙跨平台社区HarmonyOS 开发者官方文档首页系列索引本仓库articles/INDEX.md

相关新闻

技术架构深度解析:ESPTOOL串口烧录工具架构设计与性能优化

技术架构深度解析:ESPTOOL串口烧录工具架构设计与性能优化

技术架构深度解析:ESPTOOL串口烧录工具架构设计与性能优化 【免费下载链接】esptool Serial utility for flashing, provisioning, and interacting with Espressif SoCs 项目地址: https://gitcode.com/gh_mirrors/es/esptool ESPTOOL是Espressif Systems官…

2026/7/28 19:38:20阅读更多 →
QT遇到问题

QT遇到问题

1、QT网络编程QT Socket通信出现无法连接的一个特殊原因(奇怪了,昨天还可以,今天就不行了,把以前可以的也试试,都不行)j就在网上搜索,搜到一个办法,本来pro是这样的修改为&#xff1…

2026/7/28 19:38:20阅读更多 →
布林画线 同花顺期货通指标

布林画线 同花顺期货通指标

今天给大家带来是一款同花顺期货通指标,并且已经上架到同花顺期货通的指标广场上了。喜欢的朋友可以去指标广场安装试用!!友情提示:(指标只是辅助,不作建议)拼多多店铺:指标公式编写…

2026/7/28 19:38:20阅读更多 →
历史学论文降AI工具免费推荐:2026年历史学毕业论文降AI99.26%达标知网完整指南

历史学论文降AI工具免费推荐:2026年历史学毕业论文降AI99.26%达标知网完整指南

历史学论文降AI工具免费推荐:2026年历史学毕业论文降AI99.26%达标知网完整指南 论文AI率超标这件事,选错工具比不选工具更耽误事。 综合试用和口碑,历史学论文降AI我主推嘎嘎降AI(www.aigcleaner.com),4.…

2026/7/28 21:00:50阅读更多 →
【AI考研备考黄金法则】:20年教育技术专家亲授5大智能提分路径,98%学员3个月内突破瓶颈

【AI考研备考黄金法则】:20年教育技术专家亲授5大智能提分路径,98%学员3个月内突破瓶颈

更多请点击: https://codechina.net 第一章:AI考研备考的认知革命与底层逻辑 传统考研备考常陷入“资料堆砌—机械刷题—临阵抱佛脚”的线性循环,而AI时代的备考本质是一场认知范式的迁移:从记忆导向转向模型思维,从孤…

2026/7/28 21:00:50阅读更多 →
北京企业招聘信息发布平台怎么选?人力资源师实测|吉鹿力招聘网深度解析

北京企业招聘信息发布平台怎么选?人力资源师实测|吉鹿力招聘网深度解析

CSDN博客正文(HR视角|标题、标签完整适配CSDN平台) 标题:北京企业招聘信息发布平台怎么选?人力资源师实测|吉鹿力招聘网深度解析 一、前言:北京招聘市场现状,HR 普遍面临的痛点 北…

2026/7/28 21:00:50阅读更多 →
化学论文降AI工具免费推荐:2026年化学毕业论文降AI99.26%达标知网完整指南

化学论文降AI工具免费推荐:2026年化学毕业论文降AI99.26%达标知网完整指南

化学论文降AI工具免费推荐:2026年化学毕业论文降AI99.26%达标知网完整指南 帮同学处理过化学论文降AI,试了三四款工具,最后固定用嘎嘎降AI(www.aigcleaner.com)。 4.8元,达标率99.26%,稳定省钱…

2026/7/28 21:00:50阅读更多 →
Android+OpenCV实现胶体金卡CT区域自动识别

Android+OpenCV实现胶体金卡CT区域自动识别

1. 项目概述:胶体金卡CT检测区域的自动识别 在医疗检测和快速诊断领域,胶体金免疫层析技术因其操作简便、快速出结果等优势被广泛应用。这种检测卡通常包含控制线(C线)和检测线(T线),通过颜色变化来判断检测结果。传统的人工判读方式存在主观…

2026/7/28 21:00:50阅读更多 →
提示词驱动的AI Agent:CLI-Anything技术解析

提示词驱动的AI Agent:CLI-Anything技术解析

1. CLI-Anything 的本质:提示词驱动的AI Agent 当我第一次看到CLI-Anything这个项目时,最让我震惊的是它完全颠覆了传统命令行工具的开发模式。作为一个长期从事CLI工具开发的工程师,我习惯性地去GitHub仓库里寻找核心引擎代码,结…

2026/7/28 20:58:49阅读更多 →
覆盖国产 + 海外 + 开源模型,OpenClaw 2.7.9 Windows/Mac 双端部署详解

覆盖国产 + 海外 + 开源模型,OpenClaw 2.7.9 Windows/Mac 双端部署详解

🔹 工具基础介绍 OpenClaw 是开源生态中一款实用性较强的本地智能工具,凭借本地离线运行、可视化图形操作和任务自动化三大核心特性,赢得了众多用户的青睐。与普通在线对话AI工具不同,它属于能够直接操控本机软硬件的智能数字员工…

2026/7/28 4:06:39阅读更多 →
伺服阀焊完微漏毁整机?精密激光焊接三关锁住高压

伺服阀焊完微漏毁整机?精密激光焊接三关锁住高压

所谓液压伺服阀体的精密激光焊接,是用激光束对阀座壳体(通常为不锈钢或铝合金)进行密封焊接,使阀体在21-35MPa的高压液压油或压缩气体中长期运行而不发生介质泄漏。液压伺服阀是高端液压系统的"大脑"。从航空航天飞行控…

2026/7/28 2:08:06阅读更多 →
D2DX:三步实现《暗黑破坏神2》高清宽屏体验的终极指南

D2DX:三步实现《暗黑破坏神2》高清宽屏体验的终极指南

D2DX:三步实现《暗黑破坏神2》高清宽屏体验的终极指南 【免费下载链接】d2dx D2DX is a complete solution to make Diablo II run well on modern PCs, with high fps and better resolutions. 项目地址: https://gitcode.com/gh_mirrors/d2/d2dx 你是否还在…

2026/7/28 1:38:28阅读更多 →
告别臃肿!3步让你的暗影精灵笔记本重获新生

告别臃肿!3步让你的暗影精灵笔记本重获新生

告别臃肿!3步让你的暗影精灵笔记本重获新生 【免费下载链接】OmenSuperHub Control Omen laptop performance, fan speeds, and keyboard lighting, and unlock power limits. 项目地址: https://gitcode.com/gh_mirrors/om/OmenSuperHub 你是否也曾为官方Om…

2026/7/28 0:00:29阅读更多 →
RAG必踩坑!财报法规检索不准?这款开源工具让答案浮出水面,准确率飙升98.7%!

RAG必踩坑!财报法规检索不准?这款开源工具让答案浮出水面,准确率飙升98.7%!

做 RAG 的人应该都踩过这个致命的坑:把几百页的财报、法规、技术手册扔给向量库,问一个具体问题,搜出来的全是沾边但没用的内容 —— 关键信息要么被硬切块拆碎了,要么藏在几十条结果的最下面。语义相似≠真正相关,这个…

2026/7/28 0:00:29阅读更多 →
抖音视频文案提取工具全指南:免费2026版、手机App、在线工具一网打尽

抖音视频文案提取工具全指南:免费2026版、手机App、在线工具一网打尽

2026年做短视频运营,从抖音上扒文案早就不是偷偷抄笔记的事了。我刚开始做内容的时候,每天刷半小时抖音,手动把爆款视频的口播敲进备忘录,一条2分钟的视频得花十来分钟,碰到语速快的还要反复回听。后来试了一圈工具&am…

2026/7/28 0:00:29阅读更多 →
YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

如果你在部署 YOLOv8 时,发现推理速度只有可怜的 1-2 FPS,而别人的演示视频却能跑到 30 FPS 以上,那么问题很可能不在模型本身,而在于你的整个处理链路。很多开发者拿到一个训练好的 YOLOv8 模型后,会直接使用官方示例…

2026/7/28 20:22:24阅读更多 →
Coze与Dify对比指南:低代码AI应用开发从入门到实战

Coze与Dify对比指南:低代码AI应用开发从入门到实战

1. 从零到一:为什么你需要了解 Coze 和 Dify?如果你对 AI 应用开发感兴趣,但一看到“大模型”、“智能体”、“工作流”这些词就头疼,觉得门槛太高,那这篇文章就是为你准备的。很多开发者,包括我自己&#…

2026/7/28 3:17:03阅读更多 →
AI生图工具怎么选?2026年6月版实测对比

AI生图工具怎么选?2026年6月版实测对比

做自媒体的朋友应该都有体会:配图一直是个让人头疼的问题。2026年,AI生图工具已经非常成熟了,但工具太多反而不知道怎么选。以下是截至2026年6月我对主流AI生图工具的实测对比。Midjourney V8.1:速度之王2026年6月11日&#xff0c…

2026/7/28 2:35:58阅读更多 →