悬浮窗使用指导
不可见组件,一个组件支持两种显示方式:
| 显示方式 | 调用 | 用途 |
|---|---|---|
| 圆形悬浮球 | ShowButton() |
新建、客服、快捷操作入口,轻点触发被点击事件 |
| 悬浮窗口 | ShowComponent(布局) |
将标签、按钮等组成的布局浮起来,做计时器、工具面板、小窗口;内部按钮照常触发自己的事件 |
两种方式共用可拖动、初始位置、水平间距、垂直间距和启用阴影属性。再次显示另一种方式会替换当前悬浮内容,不会额外叠加一个窗口。默认不启用阴影。
两种浮法,由在其它应用上层(OverOtherApps)属性决定:
| 只在本应用内(默认) | 在其它应用上层 | |
|---|---|---|
| 显示范围 | 浮在本应用当前屏幕上方 | 切到桌面、打开其它应用也一直显示 |
| 权限 | 不需要 | 需要用户允许「显示在其他应用的上层」 |
| 典型用途 | 新建、回到顶部、客服入口等悬浮按钮 | 桌面悬浮球、悬浮计时器、悬浮歌词、悬浮小窗 |
浮起来的布局里的按钮、标签照常可以点、可以改文字;关闭(Close)后布局放回原来的位置。
布局里有要拖动的组件(虚拟摇杆、滑动条等)时,把可拖动设为假,否则拖它们会把整个悬浮窗拖走——
游戏里把摇杆叠在画布上方就是这样做的,见摇杆叠在画布上方。
本组件合并了第三方拓展 FloatActionBtn 与 FloatingView 的常用功能。
快速上手:应用内悬浮按钮
拖一个悬浮窗到屏幕,不用改任何属性,屏幕打开时显示悬浮按钮,点它弹出提示:
各案例独立使用;组合到同一屏幕时,将同名事件的处理合并到一个事件积木中。
when Screen1.Initialize() {
悬浮窗1.ShowButton()
}
when 悬浮窗1.Click() {
对话框1.ShowAlert("点了悬浮按钮")
}
避开底部 Tab 栏:独立设置两个间距
设计器属性里直接设置水平间距和垂直间距,二者独立,默认均为 16;不再提供把 X、Y 一起修改的旧“边距”。例如 Tab 栏高 64,希望空隙 16,就把垂直间距设为 80,水平间距保持 16。
在屏幕放 悬浮窗1 和非可视的 对话框1,使用下面完整代码;它与上面的快速上手是独立案例:
when Screen1.Initialize() {
悬浮窗1.HorizontalMargin = 16
悬浮窗1.VerticalMargin = 80
悬浮窗1.ShadowEnabled = false
悬浮窗1.StartPosition = "右下"
悬浮窗1.ShowButton()
}
when 悬浮窗1.Click() {
对话框1.ShowAlert("这是圆形悬浮球")
}
验证:悬浮球右侧离内容区边缘 16,底部离内容区边缘 80;只改垂直间距,左右位置不变。拖动或调用移动到指定位置时也不能进入预留区域。初始位置改左上时,相同两项控制左侧与顶部距离。间距单位与设计器组件尺寸一致,随屏幕密度缩放;间距太大时会对称缩小有效边界,优先保证窗口可见。
显示中修改间距会立即把越界部分移回允许区域,修改启用阴影也立即生效。屏幕旋转、浮窗自身尺寸变化时重新限制位置。系统悬浮模式沿用相同间距规则,但操作系统的状态栏、导航区和权限仍由系统管理;它不会自动检测你的 App 的 Tab 高度,请填写实际需避开的高度。
将一个布局显示为悬浮窗口
- 放
悬浮窗1;不勾选在其它应用上层,先测试本应用内。 - 放竖直布局
竖直布局_浮窗,宽 180、高自动、背景白色、可见为假;里面放标签(文本“工具面板”)和按钮按钮_关闭(文本“关闭”)。 - 使用本节完整代码,不与其它例子的初始化事件叠加:
when Screen1.Initialize() {
悬浮窗1.HorizontalMargin = 16
悬浮窗1.VerticalMargin = 80
悬浮窗1.ShadowEnabled = false
悬浮窗1.ShowComponent(竖直布局_浮窗)
}
when 按钮_关闭.Click() {
悬浮窗1.Close()
}
验证:浮起来的是整个工具面板,不是圆球;内部关闭按钮可以点,关闭后原布局恢复原来的隐藏状态。把上方代码中的启用阴影设为真再运行(或删掉该赋值、在设计器中勾选启用阴影),观察面板边缘的阴影;球形示例开启阴影时则沿圆球边缘显示。这里的开关控制悬浮窗组件增加的阴影;布局或子组件自己设置的阴影需在对应组件里设置。
桌面悬浮计时器
- 放一个水平布局(改名
水平布局_计时),里面放一个标签标签_计时,布局设背景色、把它的可见设为假(平时不占位置); - 悬浮窗的在其它应用上层勾选为真;再放一个计时器;
- 第一次需要用户授权悬浮窗权限,授权后回到应用会触发「悬浮窗权限结果」:
global seconds = 0
when 按钮_开始.Click() {
if 悬浮窗1.HasOverlayPermission() {
悬浮窗1.ShowComponent(水平布局_计时)
} else {
悬浮窗1.RequestOverlayPermission()
}
}
when 悬浮窗1.OverlayPermissionResult(已授权) {
if 已授权 {
悬浮窗1.ShowComponent(水平布局_计时)
} else {
对话框1.ShowAlert("没有悬浮窗权限,无法在桌面显示")
}
}
when 计时器1.Timer() {
seconds = seconds + 1
标签_计时.Text = join("⏱ ", seconds, " 秒")
}
when 按钮_停止.Click() {
悬浮窗1.Close()
}
回到桌面,计时小窗仍然浮在上面,可以拖到任意位置。
记住拖动后的位置:拖动结束时把坐标存进微数据库,下次显示后移回去:
when 悬浮窗1.Moved(x坐标, y坐标) {
微数据库1.StoreValue("fw_x", x坐标)
微数据库1.StoreValue("fw_y", y坐标)
}
when Screen1.Initialize() {
悬浮窗1.ShowButton()
悬浮窗1.MoveTo(微数据库1.GetValue("fw_x", 300), 微数据库1.GetValue("fw_y", 500))
}
搭建与测试
在设计器拖入本组件和案例涉及的按钮、标签、布局等组件,按案例中的名称重命名。先运行最小案例,确认事件返回,再增加业务逻辑。示例中的素材先上传到项目,服务器地址、令牌、文件路径换成自己的值。
可见组件需要有非零宽高;不可见工具组件必须由属性或方法启动。设计器展示样式不等于运行时已加载数据或绑定目标。联机测试应使用包含本组件的 AI 伴侣;涉及系统入口或权限的行为还要编译安装后验证。
属性、方法与事件速查
完整参数类型、默认值和平台说明见组件参考。下表按调用入口列出用途;有完成事件的方法在事件中读取结果。
| 入口 | 用途 |
|---|---|
按钮颜色(ButtonColor) |
悬浮按钮的底色。 |
按钮大小(ButtonSize) |
悬浮按钮的直径(像素),默认 56。 |
可拖动(Draggable) |
是否可以用手指拖动悬浮窗。 |
图标(Icon) |
悬浮按钮上的图标图片(素材文件名);留空显示加号。 |
图标颜色(IconColor) |
默认加号图标的颜色(设置了「图标」图片时不起作用)。 |
水平间距(HorizontalMargin) |
左右边缘预留距离,默认 16;与垂直间距独立,显示与移动均保留。 |
垂直间距(VerticalMargin) |
上下边缘预留距离,默认 16;增大可避开底部 Tab 栏。 |
启用阴影(ShadowEnabled) |
默认假;球形与窗口均可设置,显示中立即生效,Android 5.0 及以上支持。 |
在其它应用上层(OverOtherApps) |
为真时是系统级悬浮窗:切到桌面或其它应用也一直显示(桌面悬浮球、悬浮计时器),需要用户授权悬浮窗权限;为假时只浮在本应用当前屏幕上方,不需要权限。显示中修改要重新显示才生效。 |
显示中(Showing) |
悬浮窗是否正在显示。 |
初始位置(StartPosition) |
显示时的初始位置:右下、左下、右上、左上(水平与垂直距离分别设置)。 |
X坐标(X) |
悬浮窗左上角的横坐标(像素);设置它会移动悬浮窗。 |
Y坐标(Y) |
悬浮窗左上角的纵坐标(像素);设置它会移动悬浮窗。 |
关闭(Close) |
关闭悬浮窗;悬浮的组件放回原来的位置。 |
有悬浮窗权限(HasOverlayPermission) |
是否已有悬浮窗权限(「在其它应用上层」时需要;安卓 6 以下默认有)。 |
移动到指定位置(x坐标,y坐标)(MoveTo) |
把悬浮窗移到指定位置(左上角坐标,像素)。 |
申请悬浮窗权限(RequestOverlayPermission) |
打开系统设置让用户允许「显示在其他应用的上层」;回到应用后触发「权限结果」。 |
显示悬浮按钮(ShowButton) |
显示圆形悬浮按钮(大小、颜色、图标见外观属性),点击触发「被点击」。 |
悬浮显示组件(组件)(ShowComponent) |
把屏幕上的一个组件(通常是一个布局,里面放计时文字、按钮等)悬浮显示;它会从原位置移进悬浮窗,「关闭」时放回原位置。组件里的按钮照常可以点。 |
被点击时(Click) |
轻点悬浮按钮或悬浮组件的空白处时触发(拖动不算点击)。 |
拖动结束时(x坐标,y坐标)(Moved) |
拖动结束时触发,参数是新位置的左上角坐标(像素)。 |
悬浮窗权限结果(已授权)(OverlayPermissionResult) |
调用「申请悬浮窗权限」并回到应用后触发,granted 为是否已获得权限。 |
常见问题与验收
| 检查项 | 操作与预期 |
|---|---|
| 初始化 | 对照案例检查是否已经调用加载、注册、连接或显示方法;仅拖入组件不会替你执行这些步骤。 |
| 结果返回 | 将成功事件和失败事件都接到标签,记录事件参数;异步操作完成前不读取结果属性。 |
| 输入配置 | 检查素材名大小写、网址是否为直接资源地址、文件是否存在、编号和索引是否在范围内。 |
| 平台与权限 | 按组件参考中的平台说明测试;授权被拒绝时应有明确提示,不继续假定操作成功。 |
| 最小案例 | 先验证页面中的最小案例,再验证第二个场景;重复操作、取消、返回屏幕后结果应符合事件说明。 |
完整 .aia 源码与操作指导
一个工程测试圆形悬浮球和真实布局工具窗口:独立横纵间距、阴影、拖动、坐标、素材图标及权限。默认只在本应用内显示,不弹跨应用授权;鸿蒙系统不支持跨应用悬浮,界面和文档明确反馈。
导入 FloatingWindowAllFeatures.aia,连接最新伴侣,或编译独立安装包。真机/伴侣运行尚未实测。
| API / 功能 | 操作入口 | 预期结果 |
|---|---|---|
| ShowButton、ShowComponent、Close、Showing | 显示球、工具窗口、关闭;窗口内部计数/关闭 | 圆球与真实布局互相替换,内部按钮照常工作,不叠加窗口 |
| Draggable、Moved、Click | 开启拖动后拖、轻点;关闭拖动再试 | 拖动结束实际坐标,轻点计数;拖动不当作点击 |
| HorizontalMargin、VerticalMargin、ShadowEnabled | 分别改水平16/垂直80,开关阴影、应用后显示 | 独立间距避开底部区域,默认无阴影;阴影沿球或窗口边缘 |
| ButtonSize、ButtonColor、IconColor、Icon | 改直径、颜色、加号/素材图标 | 圆球直径和配色实际变化;图标图片时加号色不生效 |
| StartPosition、MoveTo、X、Y | 四角、MoveTo、分别设坐标 | 实际位置读回;边界与预留间距可能夹紧目标坐标 |
| OverOtherApps、HasOverlayPermission、RequestOverlayPermission、OverlayPermissionResult | 安卓申请权限、勾跨应用、应用再显示;鸿蒙尝试 | 安卓按真实权限决定;鸿蒙拒绝且有具体提示,不宣称跨应用成功 |
| 属性和设计器全部项 | 读取状态、查看设计器 | 所有配置可查;运行默认本应用内、可拖、无阴影 |
| 记住位置、关闭恢复布局 | 勾记住拖动,关闭再显示;显示工具窗口后关闭 | 位置信息来自实际拖动,窗口原隐藏状态恢复 |
所有返回值均用于界面反馈,错误由底部错误区展示。设计器采用明确非默认配置,初始化与界面同步。API 覆盖检查按最终 AIA 检查方法、事件、属性读取与设置及设计器配置,不能替代真实设备验证。
悬浮球与工具窗口
导入方法:项目 → 导入项目(.aia)→ 选择下载的 .aia 源码文件。 一个工程测试圆形悬浮球和真实布局工具窗口:独立横纵间距、阴影、拖动、坐标、素材图标及权限。默认只在本应用内显示,不弹跨应用授权;鸿蒙系统不支持跨应用悬浮,界面和文档明确反馈。 覆盖检查 44/44。首次载入及保存重开均0个错误,真实后台导入、安装包编译通过;真机/伴侣/硬件联调尚未实测。全部属性读写、方法与事件的操作入口和预期结果见组件指导。
操作顺序
初次运行应显示本应用内的圆形加号球,底部预留80、右侧预留16。修改配置时会先关闭,点击“显示球”或“显示工具窗口”应用新模式;不要把关闭后的Showing=false当成故障。
阴影默认关闭。勾阴影后应用、再显示;两个间距独立修改。横纵坐标可能被允许边界夹紧,以实际读回为准。关闭拖动适合窗口里有滑块/摇杆的场景。工具布局原本隐藏,关闭浮窗后恢复隐藏,计数文本仍保留。
安卓跨应用测试请编译独立安装:先申请权限,在系统设置允许,回来查看实际权限,勾跨应用、应用,再显示;拒绝则不能显示。鸿蒙HasOverlayPermission与权限结果均为假,跨应用显示应报告不支持,可取消该开关回到应用内模式继续测试。没有将不支持的系统能力包装成成功。
图标ball.png复制自仓库aiplayapp/assets/share.png,不修改图片字节。默认加号时才测试IconColor。
扫码添加客服咨询