写点什么

HarmonyOS 实战:实现任意拖动的应用悬浮窗口

作者:IT小码哥
  • 2025-05-27
    北京
  • 本文字数:1113 字

    阅读完需:约 4 分钟

前言

为了增加应用程序功能的丰富性和便利性,很多应用都会提供一个悬浮窗口实现多页面显示。特别是一些性能检测工具,比如 dokit 。在鸿蒙上怎么实现类似的全局悬浮窗口呢?阅读完本篇文章你将学会在鸿蒙上如何实现这一功能。

实现效果

需求分析

要想实现全局悬浮窗口,必须满足以下几个要求:


  1. 窗口可以悬浮在任意页面。

  2. 窗口可以跟随手势拖动。

  3. 边界处理。

技术实现

在 ArkUI 中,页面只有 Window 和 View 两种组成。View 通常都是显示在 Window 中,如果要想实现一个可以在任意页面都能停留显示的悬浮窗,只能通过 window 来实现。


  1. 通过 windowState 调用 createSubWIndow 来创建一个子 Window。


 this.windowState.createSubWindow("subWindow", (err: BusinessError, window) => {     
})
复制代码


  1. 对于 windowState 的获取,一般都在 EntryAbility 中的 onWindowStateCreate 中提供,如果不想通过传递参数的方式获取 windowStage,系统也提供了工具类可以在任意地方获取。


//存储windowStageWindowManager.setWindowStage(windowStage);//获取windowstage this.windowState = WindowManager.getWindowStage()
复制代码


  1. 初始化 Window。url 为 window 页面的路径。


     window.setWindowLayoutFullScreen(false) //设置window是否全屏显示      window.setUIContent(url, (error) => {        window.showWindow((error) => {          window.setWindowBackgroundColor("#00000000") //设置window背景色        })
})
window.resize(this.size, this.size)//设置window大小 window.moveWindowTo(this.locationX, this.locationY) //设置window的初始位置
复制代码


  1. 手势移动,通过调研 PanGesture()的 onActionUpdate 方法不断更新 window 的位置。



.gesture(GestureGroup( GestureMode.Exclusive, PanGesture().onActionUpdate((event)=>{ this.currentWindow?.moveWindowTo(event.offsetX,event.offsetY) }) ))
复制代码


  1. 边界处理,计算最小移动范围和最大移动范围。确保 window 不会移出当前页面。


 this.locationX = Math.min(Math.max(this.locationX + x, this.minX), this.maxX) this.locationY = Math.min(Math.max(this.locationY + y, this.minY), this.maxY)
复制代码


  1. window 销毁。当退出应用时,需要将 window 关闭,调用 window 的 destroyWindow 方法销毁 window。


 this.contentWindow.destroyWindow(() => {        this.contentWindow = undefined      })
复制代码

总结

通过 window 不仅能实现全局悬浮窗,还可以实现自定义弹窗,Poupwindow,toast 等一系列弹窗。使用 window 的好处在于可以彻底和当前页面分离,不依赖页面存在。可以实现在任意地方弹窗。快动手试试吧!


用户头像

IT小码哥

关注

还未添加个人签名 2021-04-29 加入

还未添加个人简介

评论

发布
暂无评论
HarmonyOS实战:实现任意拖动的应用悬浮窗口_鸿蒙 Ability_IT小码哥_InfoQ写作社区