更新记录

1.0.0(2026-09-11)

首次发布。

新增

  • 全局悬浮窗核心:Android WindowManager(应用内 TYPE_APPLICATION / 桌面悬浮 TYPE_APPLICATION_OVERLAY),iOS 独立 UIWindow(windowLevel=2001,不抢占 keyWindow)。
  • 跨页面 / Tab 切换不消失;Android 支持退后台 / 桌面后台悬浮(需权限,未授权自动降级并回调)。
  • 丝滑拖拽(Android ValueAnimator / iOS 插值动画),单击与拖拽自动区分(touchSlop 8dp)。
  • 自动左右贴边吸附、贴边半隐藏(约 40% 滑出屏幕,0.7s 后触发)、触摸 / 点击自动展开。
  • 全样式自定义:形状(circle / rounded_rect / square)、边框、纯色背景、线性 / 径向渐变(CAGradientLayer / GradientDrawable)、背景图(fill / fit / center / tile)、圆角裁切、边框。
  • 内容自定义:中心文字(大小 / 颜色 / 字重)、中心图标、左右侧图标、图文混排、内边距,全部动态更新即时生效。
  • 权限闭环:checkPermission / requestPermission + onPermissionGranted / onPermissionDenied 回调。
  • 10 个生命周期与交互事件,负载统一 UTSJSONObject,双端一致。
  • 图片内存 + 磁盘两级缓存(应用沙盒 cache 目录),网络图片不重复下载。
  • Demo 演示工程:主控台(8 大功能区)、Tab 页 B 存活测试、nvue 页 C 兼容测试。

平台兼容性

uni-app(5.24)

Vue2 Vue2插件版本 Vue3 Vue3插件版本 Chrome Safari app-vue app-nvue app-nvue插件版本 Android Android插件版本 iOS iOS插件版本 鸿蒙
1.0.0 1.0.0 × × - 1.0.0 5.0 1.0.0 14 1.0.0 ×
微信小程序 支付宝小程序 抖音小程序 百度小程序 快手小程序 京东小程序 鸿蒙元服务 QQ小程序 飞书小程序 小红书小程序 快应用-华为 快应用-联盟
× × × × × × × × × × × ×

全局悬浮窗 omni-float-window

UTS 实现的双端原生悬浮窗插件(Android Kotlin / iOS Swift 由 UTS 编译生成),无 GPL 风险、可闭源商用

支持全局悬浮、桌面后台悬浮(Android)、跨页面 / Tab 切换不消失、丝滑拖拽、自动左右贴边、贴边半隐藏,纯色 / 渐变 / 背景图全样式自定义。Vue 页面与 nvue 页面通用,不限制页面类型。

支持端:App-Android(5.0+,minSdk 21)、App-iOS(14.0+)| H5 / 小程序 / 鸿蒙不支持


为什么选它

  • 真原生窗口:Android 使用 WindowManager(桌面悬浮为 TYPE_APPLICATION_OVERLAY 系统窗口),iOS 使用独立 UIWindow(windowLevel 高于 alert 且不抢占 keyWindow),不依赖任何页面组件,页面刷新 / 路由跳转 / Tab 切换均不消失。
  • 一套 API 双端一致:事件名、负载字段、参数单位由共享契约 interface.uts 统一,Android / iOS 行为一致。
  • 丝滑拖拽:Android ValueAnimator / iOS 插值动画,拖拽零卡顿;自动判断单击与拖拽(touchSlop),互不干扰。
  • 贴边与半隐藏:松手自动吸附左 / 右边缘;静止约 0.7s 后约 40% 滑出屏幕半隐藏,触摸或点击自动展开。
  • 全样式自定义:形状(圆形 / 圆角矩形 / 直角)、边框、纯色、线性 / 径向渐变、背景图(fill / fit / center / tile),全部动态修改即时生效,无需重建
  • 图片自动缓存:内存 + 磁盘两级缓存(应用沙盒 cache 目录),网络背景图 / 图标不会重复下载。
  • 权限闭环checkPermission 检测 → requestPermission 自动跳转系统授权页 → 结果回调;未授权自动降级为应用内悬浮,不崩溃。
  • 生命周期安全closeFloatWindow 彻底销毁窗口、视图与回调,无残留、无内存泄漏。
  • 隐私干净:不采集、不上传任何用户数据,全部逻辑本地执行。

快速上手

1. 最小可用示例(vue 或 nvue 页面均可)

import { showFloatWindow } from '@/uni_modules/omni-float-window'

showFloatWindow({
  width: 90,
  height: 90,
  contentText: '悬浮窗',
  onClick: (data) => {
    uni.showToast({ title: '点击了悬浮窗', icon: 'none' })
  }
})

2. Android 桌面后台悬浮(推荐先申请权限)

import { checkPermission, requestPermission, showFloatWindow } from '@/uni_modules/omni-float-window'

checkPermission((granted) => {
  if (granted) {
    showFloatWindow({ globalDesktop: true, contentText: '全局悬浮' })
  } else {
    requestPermission((ok) => {
      // ok = true 已授权;false 用户拒绝(此时 show 会自动降级为应用内悬浮)
      showFloatWindow({ globalDesktop: ok, contentText: '全局悬浮' })
    })
  }
})

Android 宿主需声明 SYSTEM_ALERT_WINDOW 权限(在 manifest.json → app-plus → distribute → android → permissions 中添加,插件 demo 工程已内置;云打包时插件会自动带入)。

3. 完整示例

插件内置 8 个功能分区的演示控制台:uni_modules/omni-float-window/demo/index.vue(主控台)、page-b.vue(Tab 存活测试)、page-c.nvue(nvue 兼容测试)。将本插件导入工程后即可直接运行。


API 方法(17 个)

方法 说明
showFloatWindow(options) 显示悬浮窗(首次调用创建;已显示时等效 updateConfig 应用最新配置)
hideFloatWindow() 隐藏(保留配置与视图,再次 show 快速恢复)
closeFloatWindow() 关闭并彻底销毁,清除全部配置与回调
checkPermission(cb) 检测悬浮窗权限,cb(granted: boolean);iOS 恒为 true
requestPermission(cb) 申请权限(Android 自动跳转系统授权页),cb(granted: boolean)
setAlpha(alpha) 整体透明度 0.0 ~ 1.0
setPosition(x, y) 设置位置(dp,屏幕左上角原点),自动夹取屏幕边界
setSize(width, height) 设置尺寸(dp),即时生效
setShape(shape) 形状:circle / rounded_rect / square
setBorder(width, color) 边框(dp / 颜色字符串),width<=0 去除边框
setBackgroundColor(color) 纯色背景(同时关闭渐变)
setGradientColor(type, start, end) 渐变背景:linear / radial
setBackgroundImage(url, mode) 背景图,modefill / fit / center / tile;url 空字符串清除
setContentText(text) 中心文字,空字符串隐藏
setIcon(url) 中心图标(文字上方),空字符串隐藏
updateConfig(options) 局部更新:仅传需要修改的字段(含全部样式 / 行为 / 回调),即时生效

单位约定:所有尺寸 / 位置参数单位为 dp(iOS 上 1dp≈1pt);textSizesp 渲染。 颜色约定:#RRGGBB 不透明,#AARRGGBB 含透明度(AA 为透明度,FF 不透明,与 Android 约定一致),#RGB 精简写法。 图片地址:支持 http(s)://、本地绝对路径、file:// 路径;Android 额外支持工程相对路径(如 static/xx.png,自动转绝对路径)。

Props 参数表(FloatWindowOptions)

所有字段均可选。showFloatWindow 首次创建时生效;之后可通过 updateConfig 局部更新,无需重建悬浮窗

基础

参数 类型 默认值 说明
width number 90 宽(dp)
height number 90 高(dp)
defaultX number 贴右留 12dp 初始位置 X(dp)
defaultY number 屏高 30% 初始位置 Y(dp)
alpha number 1.0 整体透明度 0.0~1.0
dragEnable boolean true 是否允许拖拽
autoAdsorb boolean true 松手后自动吸附左 / 右边缘
autoHideEdge boolean true 吸附后静止 0.7s 半隐藏(约 40% 滑出屏幕),触摸 / 点击展开
globalDesktop boolean false 桌面后台悬浮开关,见下方说明

globalDesktop 说明

  • Android true:系统悬浮窗(API26+ TYPE_APPLICATION_OVERLAY),退后台 / 回桌面仍显示,需要「显示在应用上层」权限;未授权时自动降级为应用内悬浮并触发 onPermissionDenied
  • Android false:应用内悬浮(TYPE_APPLICATION,挂在主 Activity 的 WindowManager),跨页面 / Tab 不消失,退到桌面不显示,无需任何权限
  • iOS:应用内全局 UIWindow 悬浮(跨页面不消失)。iOS 系统限制不支持退后台 / 桌面显示,此开关在 iOS 上不产生系统级差异。
  • 运行中切换该开关会自动重建窗口(updateConfig 已处理)。

形状 / 边框

参数 类型 默认值 说明
shape string rounded_rect circle(以宽高较小者为直径)/ rounded_rect / square
borderRadius number 20 圆角半径(dp),rounded_rect 时生效
borderWidth number 0 边框宽度(dp),0 为无边框
borderColor string #80FFFFFF 边框颜色

背景

参数 类型 默认值 说明
bgColor string #E62979FF 纯色背景(渐变开启时作为渐变底色)
bgGradientEnable boolean false 渐变背景开关
bgGradientType string linear linear(左上→右下)/ radial(中心向外)
bgGradientStartColor string #FF2979FF 渐变起始色
bgGradientEndColor string #FF00C6A7 渐变结束色
bgImage string "" 背景图地址;空字符串清除
bgImageMode string fill fill 拉伸铺满 / fit 等比完整 / center 等比居中裁剪 / tile 平铺

背景图自动跟随形状裁切(圆形 / 圆角均生效)。

内容

参数 类型 默认值 说明
contentText string 悬浮窗 中心文字,空字符串隐藏
textSize number 13 文字大小(sp)
textColor string #FFFFFFFF 文字颜色
textFontWeight string bold normal / bold
icon string "" 中心图标(文字上方),空字符串隐藏
iconWidth number 28 中心图标宽(dp)
iconHeight number 28 中心图标高(dp)
leftIcon string "" 左侧图标,空字符串隐藏
rightIcon string "" 右侧图标,空字符串隐藏
padding number 8 内容内边距(dp)

支持图文混排:中心图标 + 文字垂直排列、左右图标独立控制,全部可动态更新。

事件(10 个)

回调负载统一为 UTSJSONObject(JS 侧即普通对象)。

事件 负载 说明
onClick {x, y} 单击(与拖拽自动区分,x/y 为悬浮窗中心点 dp 坐标)
onLongPress {x, y} 长按约 500ms
onDragStart {x, y} 开始拖拽(位移超过 touchSlop 触发一次)
onDragEnd {side, x} 拖拽结束,side = left / right / none
onAdsorb {side, x} 自动吸附完成,side = left / right
onShow {} 悬浮窗显示
onHide {} 悬浮窗隐藏
onPermissionGranted {granted:true} 权限已授予
onPermissionDenied {granted:false} 权限被拒绝(Android 桌面悬浮将自动降级为应用内悬浮)
onConfigChanged {action, x} 任意 set 方法 / updateConfig 生效后触发,action 为方法名

注意事项

  1. UTS 插件含原生代码,标准基座无法运行,请先在 HBuilderX 中「制作自定义基座」或云打包后真机测试。
  2. iOS 因系统限制无法实现退后台 / 桌面悬浮(所有 iOS 插件均如此),globalDesktop 仅 Android 生效,文档如实标注,请按需选型。
  3. Android 未授权 globalDesktop=true 时自动降级为应用内悬浮,并通过 onPermissionDenied 通知,不会崩溃。
  4. 请在合适时机调用 closeFloatWindow() 彻底销毁悬浮窗(Demo 在页面 onUnload 中演示)。App 退出时窗口随进程销毁,无残留。
  5. 刘海屏 / 挖孔屏:位置计算基于窗口可用区域,拖拽边界已适配;如需严格避开状态栏可将 defaultY 设置为 ≥ 40。
  6. 网络背景图请确保域名可访问;图片默认缓存到应用沙盒 cache 目录,卸载 App 自动清理。

常见问题

Q:悬浮窗会被微信等桌面 App 覆盖吗? A:Android globalDesktop=true 使用系统级窗口,回桌面 / 打开其他 App 仍显示;false 或 iOS 时仅在自家 App 内显示。

Q:拖拽时误触 onClick? A:不会。位移超过 8dp 判定为拖拽,单击事件被抑制;松手静止后才可能触发吸附与半隐藏。

Q:如何让悬浮窗一直不被半隐藏? A:updateConfig({ autoHideEdge: false }),贴边吸附保留、不再滑出。

Q:可以同时创建多个悬浮窗吗? A:当前版本为单实例设计(全局唯一悬浮窗),重复 show 等效更新配置。

更新日志

changelog.md

授权与支持

  • 纯自研代码,不含 GPL / LGPL 组件,无传染风险。
  • 支持双授权:普通授权(加密、仅云打包)与源码授权(可离线打包 / 二次开发),详见 license.md

隐私、权限声明

1. 本插件需要申请的系统权限列表:

Android 需宿主声明 SYSTEM_ALERT_WINDOW(悬浮窗权限,仅用于显示悬浮窗,由用户在系统设置中授权);网络访问(下载在线背景图/图标);存储读写(图片磁盘缓存写入应用沙盒 cache 目录)

2. 本插件采集的数据、发送的服务器地址、以及数据用途说明:

本插件不采集、不上传任何用户隐私数据,悬浮窗渲染与图片缓存等全部逻辑在用户设备本地执行

3. 本插件是否包含广告,如包含需详细说明广告表达方式、展示频率:

暂无用户评论。