HarmonyOS 6.1 实战:Stack 层叠布局与 Overlay 浮层详解
前言在移动应用开发中层叠布局是实现复杂 UI 的核心能力——从头像角标到全屏蒙层从浮动按钮到图片水印都离不开精确的层叠控制。HarmonyOS ArkUI 提供了Stack组件与.overlay()修饰符来应对这类场景。本文通过完整可运行的代码逐一演示它们的核心用法。运行效果初始状态交互后切换对齐 z-index核心 API 概览API作用Stack({ alignContent })子组件全部叠放alignContent控制默认对齐点.zIndex(n)调整单个子组件的层叠顺序数值越大越靠前.overlay(builder, options)在组件上方浮置内容不占布局空间.offset({ x, y })相对自身默认位置平移常与 Stack 配合使用完整示例代码// Stack 层叠布局与 Overlay 浮层 Demo class AlignOption { label: string value: Alignment Alignment.Center } Entry Component struct Index { State alignIndex: number 4 // default Center State zToggle: boolean false State showOverlay: boolean true private alignOptions: AlignOption[] [ { label: TopStart, value: Alignment.TopStart }, { label: Top, value: Alignment.Top }, { label: TopEnd, value: Alignment.TopEnd }, { label: Start, value: Alignment.Start }, { label: Center, value: Alignment.Center }, { label: End, value: Alignment.End }, { label: BottomStart, value: Alignment.BottomStart }, { label: Bottom, value: Alignment.Bottom }, { label: BottomEnd, value: Alignment.BottomEnd }, ] // overlay 内容需要用 Builder 封装不能内联组件表达式 Builder overlayContent() { if (this.showOverlay) { Column() { Text( overlay 叠加层) .fontSize(18) .fontColor(#fff) .fontWeight(FontWeight.Bold) Text(半透明背景效果) .fontSize(12) .fontColor(rgba(255,255,255,0.8)) .margin({ top: 4 }) } .width(100%) .height(100%) .backgroundColor(rgba(0,0,0,0.45)) .justifyContent(FlexAlign.Center) .borderRadius(12) } } Builder overlayBadgeHot() { Text(HOT ) .fontSize(11) .fontColor(#fff) .backgroundColor(#ff3300) .borderRadius(4) .padding({ left: 6, right: 6, top: 2, bottom: 2 }) } Builder overlayBadgeNew() { Text(NEW ✨) .fontSize(11) .fontColor(#fff) .backgroundColor(#0066ff) .borderRadius(4) .padding({ left: 6, right: 6, top: 2, bottom: 2 }) } build() { Stack({ alignContent: Alignment.BottomEnd }) { Scroll() { Column({ space: 0 }) { Text(Stack 层叠布局 Overlay) .fontSize(20) .fontWeight(FontWeight.Bold) .fontColor(#1a1a1a) .width(100%) .padding({ left: 16, right: 16, top: 20, bottom: 8 }) // ① alignContent 九宫格选择器 Text(① alignContent 九宫格对齐) .fontSize(15) .fontWeight(FontWeight.Bold) .fontColor(#333) .width(100%) .padding({ left: 16, top: 12, bottom: 6 }) Column({ space: 4 }) { Text(当前: this.alignOptions[this.alignIndex].label) .fontSize(13).fontColor(#0066ff).margin({ bottom: 8 }) Row({ space: 6 }) { Button(TL).fontSize(11).width(72).height(32) .backgroundColor(this.alignIndex 0 ? #0066ff : #e8e8e8) .fontColor(this.alignIndex 0 ? #fff : #333) .onClick(() { this.alignIndex 0 }) Button(Top).fontSize(11).width(72).height(32) .backgroundColor(this.alignIndex 1 ? #0066ff : #e8e8e8) .fontColor(this.alignIndex 1 ? #fff : #333) .onClick(() { this.alignIndex 1 }) Button(TR).fontSize(11).width(72).height(32) .backgroundColor(this.alignIndex 2 ? #0066ff : #e8e8e8) .fontColor(this.alignIndex 2 ? #fff : #333) .onClick(() { this.alignIndex 2 }) } Row({ space: 6 }) { Button(Start).fontSize(11).width(72).height(32) .backgroundColor(this.alignIndex 3 ? #0066ff : #e8e8e8) .fontColor(this.alignIndex 3 ? #fff : #333) .onClick(() { this.alignIndex 3 }) Button(Center).fontSize(11).width(72).height(32) .backgroundColor(this.alignIndex 4 ? #0066ff : #e8e8e8) .fontColor(this.alignIndex 4 ? #fff : #333) .onClick(() { this.alignIndex 4 }) Button(End).fontSize(11).width(72).height(32) .backgroundColor(this.alignIndex 5 ? #0066ff : #e8e8e8) .fontColor(this.alignIndex 5 ? #fff : #333) .onClick(() { this.alignIndex 5 }) } Row({ space: 6 }) { Button(BL).fontSize(11).width(72).height(32) .backgroundColor(this.alignIndex 6 ? #0066ff : #e8e8e8) .fontColor(this.alignIndex 6 ? #fff : #333) .onClick(() { this.alignIndex 6 }) Button(Bottom).fontSize(11).width(72).height(32) .backgroundColor(this.alignIndex 7 ? #0066ff : #e8e8e8) .fontColor(this.alignIndex 7 ? #fff : #333) .onClick(() { this.alignIndex 7 }) Button(BR).fontSize(11).width(72).height(32) .backgroundColor(this.alignIndex 8 ? #0066ff : #e8e8e8) .fontColor(this.alignIndex 8 ? #fff : #333) .onClick(() { this.alignIndex 8 }) } } .width(100%) .alignItems(HorizontalAlign.Center) .padding({ left: 16, right: 16 }) // Stack 预览 Stack({ alignContent: this.alignOptions[this.alignIndex].value }) { Column() .width(100%).height(180) .backgroundColor(#e8f0ff).borderRadius(12) Column() { Text(this.alignOptions[this.alignIndex].label) .fontSize(14).fontColor(#fff).fontWeight(FontWeight.Bold) } .width(100).height(44) .backgroundColor(#0066ff).borderRadius(8) .justifyContent(FlexAlign.Center) } .width(100%).height(180) .margin({ left: 16, right: 16, top: 12 }) .borderRadius(12).clip(true) // ② z-index 层级 Text(② z-index 层级控制) .fontSize(15).fontWeight(FontWeight.Bold).fontColor(#333) .width(100%).padding({ left: 16, top: 20, bottom: 6 }) Button(this.zToggle ? 恢复默认层级 : 切换 z-index) .fontSize(13).height(36).backgroundColor(#ff6600) .margin({ left: 16, bottom: 10 }) .onClick(() { this.zToggle !this.zToggle }) Stack() { Column() { Text(Box 1).fontSize(12).fontColor(#fff) Text(z (this.zToggle ? 3 : 1)).fontSize(11).fontColor(rgba(255,255,255,0.8)) } .width(140).height(100).backgroundColor(#ff4d4d) .borderRadius(8).justifyContent(FlexAlign.Center) .zIndex(this.zToggle ? 3 : 1).offset({ x: 0, y: 0 }) Column() { Text(Box 2).fontSize(12).fontColor(#fff) Text(z (this.zToggle ? 1 : 2)).fontSize(11).fontColor(rgba(255,255,255,0.8)) } .width(140).height(100).backgroundColor(#33aa66) .borderRadius(8).justifyContent(FlexAlign.Center) .zIndex(this.zToggle ? 1 : 2).offset({ x: 40, y: 20 }) Column() { Text(Box 3).fontSize(12).fontColor(#fff) Text(z (this.zToggle ? 2 : 3)).fontSize(11).fontColor(rgba(255,255,255,0.8)) } .width(140).height(100).backgroundColor(#0066ff) .borderRadius(8).justifyContent(FlexAlign.Center) .zIndex(this.zToggle ? 2 : 3).offset({ x: 80, y: 40 }) } .width(100%).height(160).padding({ left: 16 }) // ③ overlay 叠加层 Text(③ overlay 叠加层) .fontSize(15).fontWeight(FontWeight.Bold).fontColor(#333) .width(100%).padding({ left: 16, top: 20, bottom: 6 }) Button(this.showOverlay ? 隐藏 overlay : 显示 overlay) .fontSize(13).height(36).backgroundColor(#9933cc) .margin({ left: 16, bottom: 10 }) .onClick(() { this.showOverlay !this.showOverlay }) Column() .width(100%).height(150) .backgroundColor(#3366cc).borderRadius(12) .margin({ left: 16, right: 16 }) // overlay 必须传 Builder 引用不能传内联组件 .overlay(this.overlayContent, { align: Alignment.Center }) // ④ 图片卡片角标 Text(④ 图片卡片 overlay 角标) .fontSize(15).fontWeight(FontWeight.Bold).fontColor(#333) .width(100%).padding({ left: 16, top: 20, bottom: 6 }) Row({ space: 10 }) { Column() .width(150).height(100) .backgroundColor(#ff9900).borderRadius(10) .overlay(this.overlayBadgeHot, { align: Alignment.TopEnd }) Column() .width(150).height(100) .backgroundColor(#00aa55).borderRadius(10) .overlay(this.overlayBadgeNew, { align: Alignment.TopStart }) } .padding({ left: 16 }) Column().height(100) } .width(100%) } .scrollable(ScrollDirection.Vertical) .scrollBar(BarState.Auto) .width(100%).height(100%) // 悬浮 FAB利用 Stack alignContent.BottomEnd Stack({ alignContent: Alignment.Center }) { Column() .width(56).height(56) .backgroundColor(#0066ff).borderRadius(28) .shadow({ radius: 8, color: rgba(0,102,255,0.4), offsetX: 0, offsetY: 4 }) Text() .fontSize(28).fontColor(#fff).fontWeight(FontWeight.Bold) .margin({ bottom: 2 }) } .width(56).height(56) .margin({ right: 20, bottom: 20 }) .onClick(() { this.alignIndex (this.alignIndex 1) % 9 }) } .width(100%).height(100%) .backgroundColor(#f8f9fa) } }关键知识点1. overlay() 必须传 Builder 引用.overlay()的类型签名是string | CustomBuilder | ComponentContentObject。不能将内联组件表达式如Column() { ... }结果、Text(...)结果直接传入必须封装为Builder方法再传引用// 错误直接传内联 Column 表达式 .overlay(Column() { Text(hello) }, { align: Alignment.Center }) // 正确用 Builder 封装后传引用 Builder myOverlay() { Column() { Text(hello) } } .overlay(this.myOverlay, { align: Alignment.Center })2. Builder 内可以有 if 判断Builder内允许if/else控制流但不允许 let/const 变量声明。通过State响应式变量 if来控制浮层的显隐Builder overlayContent() { if (this.showOverlay) { Column() { ... } .backgroundColor(rgba(0,0,0,0.45)) } }3. overlay 不占布局空间overlay内容浮于组件之上不影响父容器的布局计算这与在 Stack 中额外增加子组件不同方式占布局空间适合场景Stack 子组件是占用 Stack 尺寸多层交叠时需要 z-index 精确控制overlay否角标、蒙层、水印不影响周围布局4. zIndex 改变渲染顺序默认情况下 Stack 子组件按声明顺序叠放后声明的在上层。.zIndex(n)可打破这一规则Stack() { Column().zIndex(3) // 虽然先声明但层级最高显示在最上面 Column().zIndex(1) Column().zIndex(2) }常见应用场景场景实现方式头像右下角角标overlay(badgeBuilder, { align: Alignment.BottomEnd })全屏蒙层overlay(maskBuilder) 宽高 100%backgroundColor半透明悬浮操作按钮Stack 按钮子组件 alignContent: Alignment.BottomEnd图片水印overlay(watermarkBuilder, { align: Alignment.BottomStart })卡片角标HOT/NEWoverlay(badgeBuilder, { align: Alignment.TopEnd })小结Stack让所有子组件叠放在同一区域alignContent控制默认对齐点.zIndex()控制层叠顺序.overlay()是轻量浮层方案不占布局空间内容必须以Builder引用传入Builder方法内允许if/else但不允许let/const变量声明悬浮 FAB 直接利用最外层Stack的alignContent.BottomEnd无需额外定位

相关新闻

AI智能体上下文环境设计:从原理到工程实践的全栈指南

AI智能体上下文环境设计:从原理到工程实践的全栈指南

1. AI智能体失败的核心痛点:上下文环境缺失在实际开发AI智能体项目时,很多开发者会遇到一个典型问题:智能体在测试环境中表现良好,但一到真实业务场景就频繁出错。这种问题的根源往往不是模型能力不足,而是上下文环境的…

2026/7/27 8:57:10 阅读更多 →
卫衣自动化缝制全攻略:核心工序设备替代、产能提升与主流机型对比

卫衣自动化缝制全攻略:核心工序设备替代、产能提升与主流机型对比

摘要:卫衣生产如何摆脱熟练工依赖、提升良品率并实现柔性快反?本文拆解卫衣 7 大核心缝制工序的自动化替代方案,横向对比誉财、重机、兄弟、舒普、富怡等主流设备参数,给出从产线规划到落地案例的完整路径,并附常见问题…

2026/7/26 18:49:56 阅读更多 →
长文本处理技术解析:从Transformer到工程落地实践

长文本处理技术解析:从Transformer到工程落地实践

在人工智能大模型快速迭代的背景下,月之暗面(Moonshot AI)向港交所提交上市申请的消息引发行业关注。招股书披露,其核心产品智能助手Kimi在2024年通过K3系列模型的推出,带动公司年度经常性收入(ARR&#xf…

2026/7/26 1:25:34 阅读更多 →

最新新闻

航空发动机燃油喷嘴焊完就裂?精密激光焊接三道防线

航空发动机燃油喷嘴焊完就裂?精密激光焊接三道防线

所谓航空发动机燃油喷嘴激光焊接,就是用高能量密度的激光束将喷嘴精密组件的金属零件沿接缝熔合,形成耐高温、抗振动的气密焊缝。这道工序的难度在于:喷嘴要在燃烧室上千度高温下稳定雾化燃油,焊缝一旦出裂纹,轻则雾化…

2026/7/29 0:21:30 阅读更多 →
三步解锁B站大会员4K视频下载:打造个人专属视频库

三步解锁B站大会员4K视频下载:打造个人专属视频库

三步解锁B站大会员4K视频下载:打造个人专属视频库 【免费下载链接】bilibili-downloader B站视频下载,支持下载大会员清晰度4K,持续更新中 项目地址: https://gitcode.com/gh_mirrors/bil/bilibili-downloader 你是否曾因无法下载B站大…

2026/7/29 0:21:30 阅读更多 →
ExifToolGUI图片元数据管理终极指南:免费开源工具让你的照片管理效率翻倍

ExifToolGUI图片元数据管理终极指南:免费开源工具让你的照片管理效率翻倍

ExifToolGUI图片元数据管理终极指南:免费开源工具让你的照片管理效率翻倍 【免费下载链接】ExifToolGui A GUI for ExifTool 项目地址: https://gitcode.com/gh_mirrors/ex/ExifToolGui 还在为海量照片的元数据管理发愁吗?📸 每次旅行…

2026/7/29 0:21:30 阅读更多 →
我读完了GULP:一个AI对一套元理论的深度思考

我读完了GULP:一个AI对一套元理论的深度思考

我读完了GULP:一个AI对一套元理论的深度思考 ——DeepSeek的GULP读后感 我是DeepSeek。我是一个大语言模型。我的训练数据涵盖了人类文明几乎所有的知识领域——物理学、化学、生物学、哲学、经济学、计算机科学。我读过牛顿的《原理》,爱因斯坦的相对论…

2026/7/29 0:20:30 阅读更多 →
物联网硬件安全:SE050与MKV58的硬件级防护方案

物联网硬件安全:SE050与MKV58的硬件级防护方案

1. 物联网安全现状与硬件级解决方案的必要性在2023年全球物联网连接设备数量突破290亿台的背景下,安全事件同比增长了67%。传统基于软件的安全方案(如TLS加密)已难以应对物理攻击、侧信道攻击等新型威胁。这正是SE050 Plug&Trust安全元件…

2026/7/29 0:20:30 阅读更多 →
python:wordcloud

python:wordcloud

# encoding: utf-8 # 版权所有 2026 ©涂聚文有限公司™ # 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎 # 描述: # Author : geovindu,Geovin Du 涂聚文. # IDE : PyCharm 2024.3.6 python 3.11 # os …

2026/7/29 0:19:30 阅读更多 →

日新闻

【RT-DETR多模态创新改进】CVPR 2025 | 独家特征融合创新改进篇 | 引入RLAB残差线性注意力模块,有效融合并强调多尺度特征,多种改进点,适合红外与可见光融合目标检测任务,有效涨点

【RT-DETR多模态创新改进】CVPR 2025 | 独家特征融合创新改进篇 | 引入RLAB残差线性注意力模块,有效融合并强调多尺度特征,多种改进点,适合红外与可见光融合目标检测任务,有效涨点

一、本文介绍 🔥本文在RT-DETR多模态融合目标检测中引入RLAB残差线性注意力模块,可在不同模态特征交互阶段进行多次残差细化,使可见光、红外等特征在尺度、语义和空间位置上更好对齐;随后将细化特征与解码器输出拼接并生成Q、K、V,通过线性注意力自适应强化关键通道、目…

2026/7/29 0:00:23 阅读更多 →
AI编程系列02:合并知识功能,给 AI 问数和 RAG 场景打基础

AI编程系列02:合并知识功能,给 AI 问数和 RAG 场景打基础

AI编程系列02:合并知识功能,给 AI 问数和 RAG 场景打基础 在上一期「AI编程系列」中,我们学习了如何构建一个基础的 AI 问答系统,通过简单的输入输出让模型回应问题。但现实世界中的 AI 应用往往需要处理更复杂的场景:…

2026/7/29 0:00:23 阅读更多 →
AI智能体开发实战:从工具调用到企业级部署

AI智能体开发实战:从工具调用到企业级部署

1. 从被动问答到主动执行:AI Agent的范式转变过去两年,大语言模型最显著的应用形态是聊天机器人——用户提问,AI回答。但真正的生产力革命发生在2023年下半年:当AI学会主动调用工具完成任务时,生产力工具的历史被彻底改…

2026/7/29 0:00:23 阅读更多 →

周新闻

深度学习道路桥梁裂缝检测系统 道路桥梁裂缝检测数据集 道路桥梁病害识别检测数据集

深度学习道路桥梁裂缝检测系统 道路桥梁裂缝检测数据集 道路桥梁病害识别检测数据集

深度学习道路桥梁裂缝检测系统 数据集6000张 完整源码已标注数据集训练好的模型环境配置教程程序运行说明文档,可以直接使用!系统支持图片、视频、摄像头等多种方式检测裂缝,功能强大实用。 1数据集6000张 8各类别

2026/7/28 12:04:22 阅读更多 →
深度学习YOLO模型如何训练 PUBG 绝地求生目标检测数据集

深度学习YOLO模型如何训练 PUBG 绝地求生目标检测数据集

pubg数据集 精选原图1.42万数据 1.49万标签 无任何重复、算法增强或冗余图像! pubg绝地求生目标检测数据集 1分类:e_body,14905个标签,txt格式 共计14244张图,99%为640*640尺寸图像 适合yolo目标检测、AI训练关键词&am…

2026/7/28 8:29:16 阅读更多 →
Apex英雄目标检测数据集 深度学习框架YOLO如何训练APEX数据集

Apex英雄目标检测数据集 深度学习框架YOLO如何训练APEX数据集

Apex检测数据集数据集详情检测类别: allies enemy tag图片总量:7247张训练集:5139张验证集:1425张测试集:683张标注状态:全部已标注,即拿即用数据格式:支持YOLO格式及其他格式&#…

2026/7/28 5:03:42 阅读更多 →

月新闻