Skip to content

悬浮球 ​

屏幕上其实有两种用法不同的球,不要混在一起:

需要自定义面板内容(进度、按钮、文案)时,请用 悬浮窗 FloatPage,不要扩写本页的 menus。

Pro 开发器项目里(点「运行」之后,以及打包 App)
出现工程列表、编辑器等点「运行」进入项目页面后
作用保持屏幕常亮;任务运行时旋转;连点两次停止任务同样这三件事;配置了 menus 时可展开菜单定制
点球第一次变成关闭图标,3 秒内再点才停止展开扇形菜单(仅当配置了 floatWindow.menus 或 FloatWindow.setMenus)
未配 menus 时同上同样:第一次变关闭图标,3 秒内再点停止(与开发器一致)
任务运行中悬浮球旋转悬浮球旋转

floatWindow.menus 和 FloatWindow 只作用于项目悬浮球。在开发器里执行脚本、或还没点「运行」时,改菜单不会改变开发器那颗球。

未配置 floatWindow.menus(且未调用 FloatWindow.setMenus)时,不要写空 menus 占位;默认交互就是连点两次停止(第一次变关闭图标,3 秒内再点)。

配置了 menus 后,点项目悬浮球展开功能图标(不再用连点两次)。球可拖动,松手后吸附在左或右:

  • 贴右边:图标朝左展开
  • 贴左边:图标朝右展开
  • 靠顶 / 靠底:扇形收到有空间的一侧,避免画出屏幕
  • 空间仍不够(例如贴顶且图标较多):改为球内侧竖排

floatWindow.menus 默认可配 3 个,最多 5 个,超过只展示前 5 个。

每项在 JS 里用 FloatWindow.on 绑定;JSON 可写 onTap 作函数名提示,须与 JS 绑定同一轮交付。

关闭任务:底层逻辑 ​

对外只有 Engines.closeAll() 与 FloatWindow.stopTask() 两个入口(无其它可写 API)。

JS API关闭范围适用场景
Engines.closeAll()当前任务脚本及其子脚本自动结束:写在 tasks/*.js 里
FloatWindow.stopTask()整项项目任务 + 恢复悬浮球手动点悬浮球菜单;或非任务脚本线程上的整项结束

Engines.closeAll() 须在任务脚本执行线程内调用。悬浮球菜单回调不在该线程,不能用它停任务。

原则:用户手动停 → FloatWindow.stopTask();任务内自动停 → Engines.closeAll();非任务线程触发的整项结束 → FloatWindow.stopTask()。

详见 Engines.closeAll() 与 FloatWindow.stopTask()。

显示/隐藏这颗球、以及后台弹窗,仍用 FloatDialogs。

悬浮窗权限 ​

Android 未授予「显示在其他应用上层」时,悬浮球服务创建不了,球不会出现。是否去授权由你的 JS 决定,不要依赖系统自动弹窗。

javascript
if (!Access.isFloatWindowsEnabled()) {
    Dialogs.confirm('温馨提示', '未开启悬浮窗权限时悬浮球无法展示,是否前往系统设置授权?', function (ok) {
        if (ok) {
            Access.openFloatWindowsSetting();
        }
    });
} else {
    FloatDialogs.setFloatWindowVisible(true);
}
API作用
Access.isFloatWindowsEnabled()是否已授予悬浮窗权限
Access.openFloatWindowsSetting()打开系统悬浮窗设置,由用户自己开
FloatDialogs.setFloatWindowVisible(true/false)显示 / 隐藏这颗球(无权限时不要调用)

授权后请先回到页面,再显示悬浮球。自定义界面见 悬浮窗 FloatPage。

先看效果 ​

拖球到左/右或靠顶、靠底后再点。可改图标个数(1–5,默认 3)。左侧可看 JSON、共用菜单脚本、以及页面里如何检查权限。

配置 menus ​

写在 deekeScript.json 的 floatWindow.menus。默认 3 个,最多 5 个;超过 5 个只展示前 5 个。

json
{
  "floatWindow": {
    "menus": [
      { "id": "start", "icon": "play", "label": "开始", "onTap": "onStart", "show": "idle" },
      { "id": "stop", "icon": "close", "label": "停止", "onTap": "onStop", "show": "running", "background": "#FFE8E6" },
      { "id": "hide", "icon": "hide", "label": "隐藏", "onTap": "onHide" },
      { "id": "skip", "icon": "img/skip.png", "label": "跳过", "onTap": "onSkip", "show": "running" }
    ]
  }
}
参数类型说明
idString菜单项 id,给 FloatWindow.on / update 用
iconString内置名 close / play / hide,或工程内图片、SVG 路径
labelString图标下方短文案
onTapString点击时调用的 JS 函数名(须与 FloatWindow.on 绑定)
showStringalways(默认)、running(脚本运行中)、idle(未运行)
backgroundString圆形底色,如 #FFFFFF、#FFE8E6

开始、停止、隐藏、跑子脚本都在 FloatWindow.on 里写。

示例:绑定菜单点击 ​

common/floatMenu.js(或 tasks/*.js 开头):

javascript
function bind(state) {
  FloatWindow.on({
    start: function () {
      Engines.executeScript('tasks/sample.js');
    },
    stop: function () {
      FloatWindow.stopTask();
    },
    hide: function () {
      FloatDialogs.setFloatWindowVisible(false);
    },
    skip: function () {
      state.skipped = true;
      FloatWindow.update('skip', {
        label: '已跳过',
        background: '#E8F5E9'
      });
    }
  });
}

module.exports = { bind: bind };

任务脚本里在循环前 require('../common/floatMenu.js').bind({ skipped: false }),并与 while (!state.skipped) 共用标志。

FloatWindow.setMenus(menus) ​

运行时替换菜单。脚本结束后恢复成 JSON 配置。

javascript
FloatWindow.setMenus([
    { id: 'stop', icon: 'close', label: '停止', onTap: function () { FloatWindow.stopTask(); }, show: 'running' },
    { id: 'skip', icon: 'img/skip.png', label: '跳过', onTap: function () { skipCurrent(); } }
]);

FloatWindow.on(id, fn) ​

给某个 id 绑定点击。也可传入对象一次绑多个。JSON 里的 onTap: "onSkip" 会找同名函数,或找 on('skip') / on('onSkip') 绑过的回调。

javascript
FloatWindow.on('skip', function () {
    FloatWindow.update('skip', { label: '已跳过', background: '#E8F5E9' });
});

FloatWindow.on({
    start: function () {
        Engines.executeScript('tasks/sample.js');
    },
    stop: function () {
        FloatWindow.stopTask();
    }
});

FloatWindow.update(id, patch) ​

改某一个图标的文案、图片、底色。菜单正展开时会立刻刷新。

javascript
FloatWindow.update('skip', { label: '已跳过', icon: 'img/skip-done.png', background: '#E8F5E9' });
FloatWindow.update('skip', { visible: false });

FloatWindow.collapse() ​

收起已展开的菜单。

javascript
FloatWindow.collapse();

FloatWindow.stopTask() ​

从悬浮球停止整项项目任务,并恢复悬浮球(停旋转、还原图标、收起菜单)。菜单里点「停止」必须用本方法,不要用 Engines.closeAll()。

与 Engines.closeAll() 对比见上文 关闭任务:底层逻辑。

javascript
FloatWindow.on({
    stop: function () {
        FloatWindow.collapse();
        FloatWindow.stopTask();
        FloatDialogs.toast('任务已停止');
    }
});

完整可运行示例请在手机端 DeekeScript Pro 底栏「示例」→「能力 → 悬浮球」中查看。源码仓库:deekeScriptV2Demo,对应文件包括:

  • pages/floatWindow/page.js:检查 / 打开悬浮窗权限、显示隐藏球、启停任务、setMenus / update / collapse
  • common/floatMenu.js:FloatWindow.on 绑定开始、停止、跳过、日志
  • common/permission.js:ensureFloat() / runScript()
  • deekeScript.json 的 floatWindow.menus

自定义界面见 悬浮窗 FloatPage。