更新记录

1.1.4(2026-10-14)

【修复】iOS 云打包编译失败

1.1.3(2026-10-13)

【修复】ios编译打包问题:适配性的问题处理

1.1.2(2026-10-13)

【新增】大面板高度自适应 【修复】iOS 端云打包编译失败问题

查看更多

平台兼容性

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) 背景图,mode:fill / fit / center / tile;url 空字符串清除
setContentText(text) 中心文字,空字符串隐藏
setIcon(url) 中心图标(文字上方),空字符串隐藏
updateConfig(options) 局部更新:仅传需要修改的字段(含全部样式 / 行为 / 回调),即时生效

单位约定:所有尺寸 / 位置参数单位为 dp(iOS 上 1dp≈1pt);textSize 按 sp 渲染。 颜色约定:#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)

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

点击展开(单击放大查看更多信息)

设置 expandContentText 后启用:单击小窗 → 悬浮窗放大到屏幕正中央,显示更详细的内容;再操作即可收起。适合行情报价、消息详情等「小窗简略 + 大窗详情」场景。

参数 类型 默认值 说明
expandContentText string "" 展开后大面板的内容,支持 \n 换行(行数不限);空字符串表示关闭点击展开
expandWidth number 220 大面板宽(dp)
expandHeight number 300 大面板高(dp);expandAutoHeight = true 时不生效
expandAutoHeight boolean true 大面板高度随内容自适应撑开(实测内容高度,紧凑不留空白);设为 false 使用固定 expandHeight;通过 updateConfig 更新内容后自适应高度自动重算

交互约定(双端一致)

  • 单击小窗 → 放大到屏幕正中央,显示 expandContentText(约 0.3s 双击判定后触发)
  • 单击大面板 → 立即收起,恢复原尺寸 / 原内容 / 原位置
  • 双击小窗 → Android 桌面悬浮模式下返回应用界面(App 在后台时);iOS 无桌面悬浮,双击无动作
  • 展开期间禁用拖拽与长按;展开 / 收起会触发 onConfigChanged(action 为 expand / collapse)
  • 收起后重新展开显示的是 expandContentText 的最新值,可用 updateConfig({ expandContentText: '...' }) 动态更新大面板内容
showFloatWindow({
  width: 90, height: 60,
  contentText: '黄金 512.30\n白银 8.15',        // 小窗:简略报价
  expandWidth: 240,
  expandHeight: 320,
  expandContentText: '黄金 Au99.99  512.30  +1.2%\n白银 Ag99.99  8.15  -0.3%\n铂金 Pt  221.60  +0.8%\n—— 单击面板收起 ——'
})

换行符说明:contentText 与 expandContentText 的换行必须是英文半角 \n(反斜杠 + 小写 n,代码字符串直接写 '\n' 即可);中文输入法的全角 \n 不生效。

事件(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 为方法名;点击展开 / 收起时为 expand / collapse

注意事项

  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:运行报 undefined is not an object (evaluating '_omniFloatWindow.xxx')? A:当前运行基座里没有编译进本 UTS 插件(Android / iOS 同理)。UTS 插件不能使用标准基座运行:请「发行 → 原生App-云打包 → 打自定义调试基座」重新打包并安装,运行时勾选「使用自定义基座运行」。若基座是在安装本插件之前打的,或插件升级后未重打基座,也会报此错误——修改工程版本号后重新打包即可。

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

Q:contentText / expandContentText 里的 \n 显示成了文字? A:换行必须是英文半角 \n(反斜杠+n)。代码里写 contentText: '第一行\n第二行' 直接生效;若是用户在输入框里手打 \n,需要先把字符串里的 \n 替换成真实换行符再传入(demo 页的 toRealNewline 方法有现成实现,含全角\n与带引号写法的容错)。

更新日志

见 changelog.md。

授权与支持

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

隐私、权限声明

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

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

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

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

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

无