HarmonyOS应用开发实战:猫猫大作战-`Stack` 的 `alignContent` 9 位、`zIndex` 层序、状态遮罩叠层套路
前言前 8 篇我们拆的主菜单元素都在Column/Row里依次排列——标题在上、按钮在中、规则在下。但实战中有一类布局是「叠」而非「排」游戏页的棋盘 棋子 顶部 HUD三层叠在一起暂停时全屏遮罩盖在棋盘上弹窗居中浮在所有内容之上。这种「Z 轴叠层」就是Stack容器的主场。本篇以「猫猫大作战」游戏页的Stack根布局为锚点把Stack的alignContent9 位、zIndex层序、状态遮罩叠层套路讲透。读完本篇你将能独立写出三层叠游戏页、全屏暂停遮罩、居中浮弹窗三种叠层布局。提示本系列不讲 ArkTS 基础语法与环境搭建假设你已跟完第 1–8 篇。一、场景拆解游戏页 Stack 根布局打开entry/src/main/ets/pages/Index.ets的build()// 来源entry/src/main/ets/pages/Index.ets build() build() { Stack() { if (this.gameState GameState.IDLE) { MainMenuView() // 主菜单 } else if (this.gameState GameState.PLAYING || this.gameState GameState.PAUSED) { GameView() // 游戏页 if (this.gameState GameState.PAUSED) { PauseOverlay() // 暂停遮罩 } } else if (this.gameState GameState.GAME_OVER) { GameOverView() // 结束页 } } .width(100%).height(100%) }关键观察Stack只有一个子元素当前状态的视图不是叠层示范。真正展示叠层的在GameView// 来源entry/src/main/ets/pages/Index.ets GameView() Stack() { // 第 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) }) }.width(100%).height(${100 / ROWS}%) }) }.width(100%).height(100%) // 第 2 层猫咪层绝对定位 Column() { ForEach(this.cats, (cat: Cat) { Text(this.getCatEmoji(cat.level)) .fontSize(30) .position({ x: ${cat.x * 100 / COLS}%, y: ${cat.y * 100 / ROWS}% }) }) }.width(100%).height(100%) // 第 3 层顶部 HUD GameHUD() } .width(100%).height(100%)三层叠结构层内容Z 序定位方式底棋盘背景网格默认最下流式铺满中猫咪层默认中间position绝对定位上顶部 HUD默认最上流式顶部对齐二、Stack 容器核心属性速览Stack是叠层容器子元素自下而上叠后写的在上默认所有子元素居中对齐。2.1 本篇用到的属性属性类型作用本篇取值widthstring | number容器宽度100%heightstring | number容器高度100%alignContentAlignment 枚举子元素对齐位默认CenterzIndexnumber子元素层序0/1/2 控序2.2 Stack vs Row/Column 区别容器子元素排列默认对齐适用Row横排依次VerticalAlign.Center横排布局Column竖排依次HorizontalAlign.Center竖排布局Stack叠层Z 轴Alignment.Center叠层、覆盖、绝对定位记忆Row/Column是「排」Stack是「叠」——排是二维布局叠是 Z 轴层序。三、alignContent 9 位对齐Alignment枚举 9 值3×3 网格枚举水平垂直说明TopStart左顶左上角Top中顶顶部居中TopEnd右顶右上角Start左中左居中Center中中居中默认End右中右居中BottomStart左底左下角Bottom中底底部居中BottomEnd右底右下角3.1 游戏页用默认 CenterStack() { Column() { /* 棋盘 */ }.width(100%).height(100%) Column() { /* 猫咪 */ }.width(100%).height(100%) GameHUD() } .width(100%).height(100%) // alignContent 不写默认 Center棋盘和猫咪层都width(100%).height(100%)鲺满alignContent无所谓——满铺就对齐。HUD 不铺满默认居中——但 HUD 要顶部对齐所以实战中要改Stack() { Column() { /* 棋盘 */ }.width(100%).height(100%) Column() { /* 猫咪 */ }.width(100%).height(100%) GameHUD() } .width(100%).height(100%) .alignContent(Alignment.Top) // HUD 顶部居中3.2 全屏遮罩用 CenterStack() { GameView() // 游戏页 PauseOverlay() // 暂停遮罩 } .alignContent(Alignment.Center) // 遮罩居中盖PauseOverlay是个半透明黑色Column居中盖在GameView上。四、zIndex 显式控层序默认 Stack 子元素后写的在上。要打破书写顺序用zIndexStack() { Column() { /* 棋盘背景 */ }.width(100%).height(100%).zIndex(0) Column() { /* 猫咪层 */ }.width(100%).height(100%).zIndex(1) GameHUD().zIndex(2) PauseOverlay().zIndex(3) // 暂停遮罩最上 }zIndex 规则数值越大越在上0 最底3 最顶。不设默认 0同 0 时后写在上。负值合法zIndex(-1)沉到所有默认 0 之下。何时显式设 zIndex状态遮罩必须最上zIndex(10)。HUD 常驻上层zIndex(5)。背景层沉底zIndex(0)或不设。提示别滥用 zIndex。多数场景靠书写顺序后写在上就够显式设 zIndex 是为了「后写但要在下」的反序情况。五、position 绝对定位猫咪层的猫咪不靠流式布局靠position绝对定位到棋盘格Text(this.getCatEmoji(cat.level)) .fontSize(30) .position({ x: ${cat.x * 100 / COLS}%, y: ${cat.y * 100 / ROWS}% })5.1 position 接受对象.position({ x: number | string, y: number | string })x距左上角水平偏移支持 vp 数字或百分比字符串。y距左上角垂直偏移同上。关键position是相对于父容器左上角父容器必须是Stack或定位容器Column/Row里用position会脱离流式布局但定位基准仍是父左上角。5.2 百分比定位的响应式.position({ x: ${cat.x * 100 / COLS}%, y: ${cat.y * 100 / ROWS}% })猫咪cat.x 2列数COLS 5则x 40%——无论屏宽多少猫咪都落在第 3 列40% 处。百分比定位是响应式绝对定位的甜区。5.3 vp 定位的固定尺寸.position({ x: 100, y: 200 }) // 距左 100vp距顶 200vp固定 vp 定位不响应屏宽适合固定尺寸棋盘如棋盘格子固定 60vp。六、实战 1三层叠游戏页Stack() { // 第 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) }) }.width(100%).height(${100 / ROWS}%) }) }.width(100%).height(100%).zIndex(0) // 第 2 层猫咪层绝对定位 Column() { ForEach(this.cats, (cat: Cat) { Text(this.getCatEmoji(cat.level)) .fontSize(30) .position({ x: ${cat.x * 100 / COLS}%, y: ${cat.y * 100 / ROWS}% }) }) }.width(100%).height(100%).zIndex(1) // 第 3 层顶部 HUD GameHUD().zIndex(2) } .width(100%).height(100%) .alignContent(Alignment.Top)七、实战 2全屏暂停遮罩Builder PauseOverlay() { Column() { Text(游戏暂停).fontSize(32).fontWeight(FontWeight.Bold).fontColor(#FFFFFF).margin({ bottom: 32 }) Button(继续游戏) .width(70%).height(56).fontSize(18).fontColor(#FFFFFF) .backgroundColor(#2ECC71).borderRadius(28) .margin({ bottom: 16 }) .onClick(() { this.gameState GameState.PLAYING; }) Button(重新开始) .width(70%).height(56).fontSize(18).fontColor(#FFFFFF) .backgroundColor(#E74C3C).borderRadius(28) .onClick(() { this.clearTimers(); this.startGame(); }) } .width(100%).height(100%) .backgroundColor(rgba(0,0,0,0.7)) // 半透明黑遮罩 .alignItems(HorizontalAlign.Center) .justifyContent(FlexAlign.Center) } // 使用叠在 GameView 上 Stack() { GameView() if (this.gameState GameState.PAUSED) { PauseOverlay() } }遮罩三要点width(100%).height(100%)齔屏遮盖。rgba(0,0,0,0.7)半透明黑让下层游戏隐约可见。justifyContent(Center) alignItems(Center)遮罩内部按钮居中。八、实战 3居中浮弹窗Stack() { GameView() // 居中浮弹窗非全屏遮罩 Column() { Text(确认重新开始).fontSize(18).fontColor(#2C3E50).margin({ bottom: 24 }) Row({ space: 12 }) { Button(取消).width(100).height(44).backgroundColor(#95A5A6).fontColor(#FFFFFF).borderRadius(22) Button(确认).width(100).height(44).backgroundColor(#E74C3C).fontColor(#FFFFFF).borderRadius(22) } } .width(70%).padding(24) .backgroundColor(#FFFFFF).borderRadius(16) .shadow({ radius: 16, color: rgba(0,0,0,0.3), offsetY: 4 }) } .alignContent(Alignment.Center) // 弹窗居中弹窗 vs 遮罩差异维度全屏遮罩居中弹窗宽高100%/100%70%/auto底色rgba(0,0,0,0.7)#FFFFFF对齐内部居中容器居中alignContent阴影无有浮起感九、调试技巧叠层怎么量加临时 border给每层加不同色 border红/蓝/绿看清层叠边界。zIndex验层序遮罩没盖住游戏查 zIndex 是否比游戏大。position验基准猫咪定位偏父容器是否Stackposition基准是否父左上角。真机看遮罩透明预览器渲染接近真机但rgba透明度可能差异以真机为准。十、性能与最佳实践Stack层数别超 5每层都是独立子树超过 5 层布局计算开销显著。zIndex别跳数用 0/1/2/3 连续别 0/10/100/1000 跳——视觉无差异还难维护。position配Stack绝对定位在Stack里最自然在Column/Row里会脱离流式但基准仍是父。遮罩rgba透明度 0.6–0.8低于 0.6 下层太清晰不像遮罩高于 0.8 太黑看不见下层。总结本篇我们从游戏页Stack根布局切入掌握Stack的alignContent9 位、zIndex层序、position绝对定位三大要点并给出了三层游戏页、全屏暂停遮罩、居中浮弹窗三种叠层布局的完整代码。核心要点Stack 是叠非排后写在上 zIndex 破序position 配 Stack 做绝对定位遮罩 100% rgba 0.7。下一篇我们将继续主菜单拆解if/else状态驱动的页面切换机制。如果这篇文章对你有帮助欢迎点赞、收藏⭐、关注你的支持是我持续创作的动力相关资源「猫猫大作战」项目源码本仓库entry/src/main/ets/pages/Index.etsStack 容器官方指南Stack API 参考Alignment 枚举开源鸿蒙跨平台社区HarmonyOS 开发者官方文档首页系列索引本仓库articles/INDEX.md

相关新闻

C#的异步编程模型:从Task到async/await的实现路径

C#的异步编程模型:从Task到async/await的实现路径

C#的异步编程从APM(异步编程模型)和EAP(基于事件的异步模式)演进到Task和async/await。当前模型在易用性和性能之间取得了较好的平衡,但其底层机制值得深入理解。 一、Task:异步操作的基本单元 Task表示一…

2026/11/10 1:18:50 阅读更多 →
HarmonyOS应用开发实战:猫猫大作战-`Column` 容器的卡片化套路

HarmonyOS应用开发实战:猫猫大作战-`Column` 容器的卡片化套路

前言 主菜单的标题、按钮是「原子元素」,但一个完整界面需要把多个原子组织成卡片。在 HarmonyOS 里,Column(垂直线性容器)是最常用的卡片骨架——它把若干子元素自上而下排列,并通过 padding、backgroundColor、bord…

2026/11/9 10:22:08 阅读更多 →
Kodi播放115网盘视频终极指南:3步实现云端原码播放

Kodi播放115网盘视频终极指南:3步实现云端原码播放

Kodi播放115网盘视频终极指南:3步实现云端原码播放 【免费下载链接】115proxy-for-kodi 115原码播放服务Kodi插件 项目地址: https://gitcode.com/gh_mirrors/11/115proxy-for-kodi 还在为本地存储空间不足而烦恼吗?想要在Kodi媒体中心直接播放11…

2026/11/5 4:26:16 阅读更多 →

最新新闻

Electron桌面应用开发实战:从环境搭建到打包发布全流程

Electron桌面应用开发实战:从环境搭建到打包发布全流程

做前端这些年,我大部分时间都在跟浏览器标签页打交道,直到第一次把桌面应用跑起来,才发现原来自己一直被限制在地址栏和刷新按钮围起来的框框里。Electron这个词,最开始是在某段时间频繁出现在同事的讨论里,一个用HTML…

2026/11/9 14:01:10 阅读更多 →
滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

简介:亚太天能T109滑盖智能锁产品说明书是一份PDF格式的官方技术文档,主要面向智能锁安装人员、终端用户及售后维护者,帮助快速掌握产品安装、配置与常见故障处理。全包仅1个PDF文件,大小4.37MB,内容结构清晰&#xff…

2026/11/9 14:56:39 阅读更多 →
PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

上个月我在调试一台高速AGV的驱动系统,整车要求空载跑到8m/s,电机转速已经拉到额定点,驱动器的输出电压也顶到了母线电压极限附近。再往上踩速度指令,转速纹丝不动,三相电流反而开始震荡。那会儿我的第一反应就是&…

2026/11/9 1:59:56 阅读更多 →
C++核心知识点:从内存管理到STL的实战指南

C++核心知识点:从内存管理到STL的实战指南

C 这门语言我前前后后折腾了十几年,用它写过嵌入式驱动、做过游戏服务端,也搭过基础组件库。每次看到新人一头扎进"C 核心知识点"这个搜索词,我其实挺感慨的——这门语言的难点从来不是语法多,而是知识点之间的耦合太深…

2026/11/9 14:01:10 阅读更多 →
T109滑盖智能锁怎么装?安装调试与故障排查全攻略

T109滑盖智能锁怎么装?安装调试与故障排查全攻略

简介:亚太天能T109滑盖智能锁产品说明书以PDF格式发布,适合智能锁用户、安装人员与售后维修人员阅读。内容围绕T109系列指纹密码刷卡锁展开,先介绍前面板、后面板、锁体、机械钥匙、电池盒盖等部件名称与功能,再给出完整安装步骤&…

2026/11/9 7:45:06 阅读更多 →
LLM知识降熵:从信息垄断到理解权下放

LLM知识降熵:从信息垄断到理解权下放

你有没有过这种经历:翻开源码注释、论文摘要或者一份专业报告,每个字都认识,连在一起却像天书。想找人聊聊,身边要么没人懂,要么懂的懒得跟你解释。后来我试着把同一段内容丢给一个大语言模型,几秒钟之后&a…

2026/11/9 14:01:11 阅读更多 →

日新闻

周新闻

月新闻