HarmonyOS 7 强化闪控窗与闪控球联动:窗口可自由拖动、侧边暂存,并与闪控球一键切换。本文讨论多形态窗口的状态归属、权限、焦点与恢复边界。
购物比价、搜题、翻译、通话和计时都希望在用户使用其他应用时保留轻入口。闪控球适合极简状态与恢复入口,闪控窗承载更完整的实时信息,主窗口负责配置和复杂任务。
真正的工程难点不是把窗口做小,而是三个形态之间切换时不丢任务、不重复执行、不抢焦点,也不泄露敏感内容。
一、先选择正确窗口方案
应用内普通子窗口实现简单,不需要特殊权限;系统悬浮窗适用于少量被允许的全局场景;PC/2in1 可评估多 UIAbility;闪控球需要ohos.permission.USE_FLOAT_BALL,并受 API 和场景审核约束。
权限必须与核心功能匹配。不能因为想做一个悬浮按钮就申请全局能力,也不能在用户拒绝后循环弹出授权。
二、领域任务独立于窗口
typeWindowMode='MAIN'|'FLOAT_VIEW'|'FLOAT_BALL'interfaceFloatingTaskState{taskId:stringtaskType:'translation'|'compare'|'timer'status:'IDLE'|'RUNNING'|'PAUSED'|'DONE'|'FAILED'mode:WindowMode version:numberupdatedAt:number}窗口只渲染任务快照,不拥有翻译、通话或下载任务。销毁闪控窗只是改变展示形态,不能终止领域任务;任务结束后则要通知所有形态收口。
三、三种形态各有职责
主窗口:首次授权、参数设置、历史记录和复杂编辑。
闪控窗:当前结果、实时进度、暂停、继续和返回主窗等少量动作。
闪控球:状态点、计时或未读提示,以及恢复闪控窗的单一动作。
如果闪控球需要滚动、输入和多级导航,就已经超出其职责;如果闪控窗遮住大面积内容,也应引导回主窗。
四、使用协调器串行化窗口操作
classFloatingWindowCoordinator{privatecurrentMode:WindowMode='MAIN'privatetransition:Promise<void>=Promise.resolve()switchTo(mode:WindowMode):Promise<void>{this.transition=this.transition.then(async()=>{if(this.currentMode===mode)returnawaitthis.hide(this.currentMode)awaitthis.show(mode)this.currentMode=mode})returnthis.transition}}快速连点可能同时触发“打开闪控窗”和“收成闪控球”。串行队列保证前一次形态切换完成后再处理下一次,避免出现两个窗口。
五、窗口位置不能直接保存像素
拖动时要避让状态栏、刘海、手势区域、键盘和系统侧边栏。屏幕旋转、分辨率或显示器改变后重新约束坐标。
interfaceNormalizedPosition{xRatio:numberyRatio:numberedge:'left'|'right'|'none'}functionrestorePosition(p:NormalizedPosition,safe:Rect):Point{returnclampToSafeArea({x:safe.left+safe.width*p.xRatio,y:safe.top+safe.height*p.yRatio},safe)}保存比例和吸附边,而不是绝对像素,才能在不同窗口尺寸下合理恢复。
六、侧边暂存仍要可发现
暂存后保留足够的露出区域和明确状态,点击恢复。避免与系统返回手势冲突,也不要遮挡其他应用的关键按钮。首次使用可以轻提示一次,之后依赖稳定位置和图形表达。
七、焦点管理优先于视觉效果
闪控窗出现时不应抢走用户正在其他应用输入的焦点。只有用户主动点击输入区域才申请焦点;隐藏时归还。键盘弹出后重新计算可用区域,不能把输入框推到屏幕外。
同一应用内主窗和子窗可使用窗口焦点切换能力,但必须限制在用户明确动作之后。
八、隐私状态要单独设计
锁屏、投屏、录屏和后台时,根据任务类型隐藏联系人、搜索内容和翻译原文。闪控球只显示中性图标或数量,不显示敏感正文。
functiontoPublicSnapshot(state:FloatingTaskState,privacy:PrivacyContext):FloatingViewModel{if(privacy.locked||privacy.screenShared){return{title:'任务进行中',detail:'',sensitive:false}}returnbuildDetailedViewModel(state)}九、恢复顺序是任务优先
进程重启后先读取 taskId 与版本,向领域服务确认任务仍有效,再决定恢复主窗、闪控窗还是闪控球。若任务已经完成,只展示结果通知;若权限被撤回,回到主窗说明,而不是重新创建悬浮入口。
asyncfunctionrestoreFloatingEntry(saved:SavedWindowState){consttask=awaittaskRepository.get(saved.taskId)if(!task||isTerminal(task.status))returnshowResultNotification(task)if(!permission.canUseFloatBall())returnopenMainWindow(task.taskId)returncoordinator.switchTo(saved.preferredMode)}十、测试矩阵
- 权限允许、拒绝、撤回和系统不支持;
- 主窗、闪控窗、闪控球快速连续切换;
- 横竖屏、分屏、自由窗口、键盘和多显示器;
- 锁屏、投屏、录屏与敏感任务;
- 进程回收、任务完成、失败和重新登录;
- 无障碍焦点、触控尺寸与减少动态效果。
describe('FloatingWindowCoordinator',()=>{it('never shows two floating modes together',async()=>{awaitPromise.all([coordinator.switchTo('FLOAT_VIEW'),coordinator.switchTo('FLOAT_BALL')])expect(windowDriver.visibleFloatingCount()).toBe(1)})})十一、上线清单
- 选择了最小权限的窗口方案;
- 领域任务与窗口生命周期完全分离;
- 形态切换串行且可重复调用;
- 坐标使用安全区域和归一化恢复;
- 焦点只在用户动作后切换;
- 锁屏与投屏具有隐私快照;
- 恢复时先验证任务和权限;
- 不支持场景可以回到主窗口。
结语
闪控窗与闪控球的价值,是让任务在多应用之间保持可见,而不是让应用永久悬浮。把任务设为单一事实源,用窗口协调器管理形态,再处理权限、焦点、坐标和隐私,才能得到稳定的多任务体验。
官方参考
- HarmonyOS 7 新能力一览:https://developer.huawei.com/consumer/cn/features/
- 全局悬浮窗方案:https://developer.huawei.com/consumer/cn/doc/doccenter-dev-faq/faqs-multi-device-deployment-8