# OverlayService
OverlayService 管理全局浮层组件(Overlay)。Overlay 是渲染在所有 Tab 和 App 上方的 UI 层,不属于任何一个 Tab,始终可见。典型用途包括全局悬浮按钮、状态栏、AI 助手入口等。
# 什么是 Overlay
在 AutumnBox 中,UI 层级从下到上依次为:
- Card -- 首页卡片,嵌入主界面
- App -- Tab 页面,打开后占据主区域
- Overlay -- 浮层,覆盖在所有内容之上
Overlay 组件由宿主在根级别渲染,独立于 Tab 切换和 App 生命周期。只要插件处于加载状态,其注册的 Overlay 就会持续显示。
# 获取方式
import { useService } from '@autumnbox/sdk/hooks';
import { OverlayService } from '@autumnbox/sdk/hooks';
// React 组件中
const overlayService = useService(OverlayService);
// pluginMain 或非 React 环境中
const overlayService = context.getService(OverlayService);
# API 一览
| 方法 / 属性 | 签名 | 说明 |
|---|---|---|
overlays | readonly overlays: IReadonlyState<readonly OverlayEntry[]> | 响应式的已注册 Overlay 列表 |
register | register({ id, component, pluginPackageName }): void | 注册一个 Overlay |
unregister | unregister(overlayId: string): void | 按 ID 注销一个 Overlay |
unregisterByPluginPackageName | unregisterByPluginPackageName(pluginPackageName: string): void | 注销某个插件的所有 Overlay |
每个 OverlayEntry 包含:
interface OverlayEntry {
id: string; // 唯一标识
component: React.ComponentType; // 渲染组件
pluginPackageName: string; // 所属插件
}
# 注册 Overlay
Overlay 应在 pluginMain 中注册,而非在 App 或 Card 组件内部。这是因为 Overlay 的生命周期与插件绑定,而不是与某个 Tab 绑定。
# 基本模式
import type { PluginContext } from '@autumnbox/sdk';
import { OverlayService } from '@autumnbox/sdk/hooks';
export function pluginMain(context: PluginContext): () => void {
const overlayService = context.getService(OverlayService);
overlayService.register({
id: 'my-overlay',
component: MyOverlayComponent,
pluginPackageName: context.pluginPackageName,
});
// 插件卸载时必须注销
return () => {
overlayService.unregister('my-overlay');
};
}
注意
务必在清理函数中调用 unregister。如果遗漏,插件卸载后 Overlay 组件仍会残留在界面上,且其引用的代码已被释放,可能导致运行时错误。
# 示例:悬浮助手按钮
一个固定在右下角的圆形按钮,点击后展开助手面板:
import { useState } from 'react';
import { Button, Drawer } from 'antd';
import { RobotOutlined } from '@ant-design/icons';
const FloatingAssistant: React.FC = () => {
const [open, setOpen] = useState(false);
return (
<>
<div style={{ position: 'fixed', bottom: 24, right: 24, zIndex: 1000 }}>
<Button
type="primary"
shape="circle"
size="large"
icon={<RobotOutlined />}
onClick={() => setOpen(true)}
/>
</div>
<Drawer
title="AI 助手"
placement="right"
open={open}
onClose={() => setOpen(false)}
>
<p>在这里实现助手功能...</p>
</Drawer>
</>
);
};
注册方式与上文"基本模式"相同,将 FloatingAssistant 作为 component 传入即可。
# 示例:全局状态栏
在顶部显示设备连接状态,Overlay 内可正常使用所有 SDK Hook:
import { useService, useServiceState } from '@autumnbox/sdk/hooks';
import { DevicesService } from '@autumnbox/sdk/services';
const DeviceStatusBar: React.FC = () => {
const devicesService = useService(DevicesService);
const [devices] = useServiceState(devicesService.devices);
const connected = devices.length > 0;
return (
<div style={{
position: 'fixed', top: 0, left: 0, right: 0, height: 28,
background: connected ? '#52c41a' : '#ff4d4f',
color: '#fff', display: 'flex', alignItems: 'center',
justifyContent: 'center', fontSize: 12, zIndex: 999,
}}>
{connected
? `已连接 ${devices.length} 台设备`
: '未连接任何设备'}
</div>
);
};
注册方式与悬浮按钮示例相同,只需替换 id 和 component。
# 下一步
- NotificationService -- 应用内通知中心
- AppService -- App 注册表
- CardService -- Card 注册表
- 应用层服务总览 -- 所有应用层 Service 速查