鸿蒙开发:基于子窗口实现应用内悬浮窗(含完整代码示例)
在现代移动应用中,悬浮窗/悬浮球是一种非常实用的交互方式,常用于展示快捷入口、实时通知、视频播放等场景。例如:
- 聊天应用中的小助手按钮
- 视频应用的画中画功能
- 游戏或工具类 App 的全局操作面板
HarmonyOS 提供了 子窗口(SubWindow)机制,结合 Window
模块和手势控制能力,开发者可以轻松构建一个支持拖拽、动画靠边、跨页面保留位置、响应点击事件的悬浮窗组件。
🎯 功能需求概述
我们希望实现以下核心功能:
编号 | 功能描述 |
✅ 场景一 | 支持动态添加/移除悬浮窗,样式可定制(圆形 & 小视频窗口) |
✅ 场景二 | 子窗口创建后,主窗口仍能正常响应系统返回手势(如侧滑返回) |
✅ 场景三 | 悬浮窗支持拖拽并自动靠边显示;跳转页面后仍保持位置不变 |
✅ 场景四 | 悬浮窗内部点击触发主窗口 Router / Navigation 页面跳转 |
✅ 场景五 | 窗口大小自适应内容组件变化 |
✅ 场景六 | 支持隐藏和销毁悬浮窗 |
✅ 场景七 | 视频类应用支持画中画后台播放与桌面返回自动恢复 |
🧱 技术选型说明
我们使用 HarmonyOS 提供的如下关键模块完成悬浮窗功能:
@ohos.window
:窗口管理模块,用于创建子窗口、设置布局、监听焦点等Router
/Navigation
:用于实现主窗口页面跳转逻辑GestureEvent
/PanGesture
:用于实现拖拽移动AppStorage
:存储公共变量如 windowStage、导航栈信息componentUtils
:获取组件尺寸用于窗口自适应调整pipWindow
:画中画功能专用接口
🛠️ 核心实现步骤
1️⃣ 获取 WindowStage 并保存到全局(EntryAbility)
💡 注意:通过
globalThis
或AppStorage
保存 windowStage,以便后续在页面中使用。
2️⃣ 创建子窗口并设置基础样式
3️⃣ 实现拖拽并自动靠边(带动画效果)
4️⃣ 主窗口响应点击事件(Router / Navigation 跳转)
使用 Router 跳转主窗口页面
使用 Navigation 跳转(需配合 AppStorage)
5️⃣ 自动适配窗口大小(基于组件变化)
6️⃣ 控制悬浮窗显隐与销毁
7️⃣ 实现视频画中画功能(PiP)
⚙️ 其他注意事项
问题 | 解答 |
如何获取 | 在 |
子窗口是否支持跨应用? | ❌ 不支持,只能用于应用内部 |
默认窗口大小是多少? | 若未设置,默认为除去安全区外的屏幕区域 |
可否在 UIExtension 中使用子窗口? | ❌ 不行,UIExtension 没有窗口对象 |
HAR/HSP 是否可用? | ✅ 只要能获取到 windowStage 即可使用 |
📦 示例工程地址
完整项目源码已上传至 Gitee:
✅ 总结
通过 HarmonyOS 提供的子窗口机制,我们可以非常灵活地实现各类悬浮窗功能,包括:
- ✅ 自定义外观与布局
- ✅ 拖拽靠边智能定位
- ✅ 跨页面状态保留
- ✅ 响应主窗口路由跳转
- ✅ 窗口自适应大小
- ✅ 画中画后台播放
这为构建更高级别的多窗口协同应用打下了坚实基础。
🔥 推荐阅读
如果你正在开发企业级 App 或需要统一用户界面风格的应用,不妨尝试使用子窗口 + UDMF + 画中画等多种能力组合,打造真正“沉浸式”的用户体验!
📌 欢迎收藏本博客,并关注后续更多 HarmonyOS 实战案例更新!