拓冰建站拓冰建站
首页 / 资讯中心 / 正文

HarmonyOS 7.0 / API 26 多窗口恢复顺序:外接屏拔掉后页面为什么要重新算窗口边界

HarmonyOS 7.0 / API 26 多窗口恢复顺序外接屏拔掉后页面为什么要重新算窗口边界这篇只讲一个点多窗口恢复顺序与外接屏断开后的窗口边界重算。版本边界先说清楚下面的写法面向 HarmonyOS 7.0 / API 26。老版本工程不要直接照搬先确认 SDK、DevEco Studio、设备系统版本和模拟器镜像是否一致。先说它解决什么鸿蒙电脑和大屏调试时外接屏拔掉以后窗口坐标、宽高和页面断点可能还沿用旧显示器的数据。问题表面看是布局错位本质是窗口恢复顺序没有先校验显示区域。如果还按 5.0 或 6.0 的旧习惯处理通常会遇到三个问题第一代码能编译但设备上行为和预期不一致第二页面状态看起来正常切换场景后就暴露边界第三性能或体验问题不是马上炸而是用户连续操作后才出现。容易复现的两个场景场景一外接屏仍在窗口从 1440 宽恢复到双栏布局列表和详情可以同时显示复现方式很简单先把页面打开到目标状态再连续做两次切换或刷新。这个时候要观察的不是按钮有没有响应而是状态有没有丢、动画有没有抖、资源有没有重复申请。场景二外接屏断开系统只剩内屏旧窗口坐标越界必须先重算 safeArea 再决定单栏或双栏第二个场景更接近线上问题用户不是按开发者预设路径走而是会来回切页面、锁屏、恢复、换方向、切到后台再回来。这个时候如果只看单次点击问题会被遮住。最小 DemotypeLayoutModesingle|doubletypeRestoreActionkeep|recalc|fallbackinterfaceDisplayArea{id:stringwidth:numberheight:number}interfaceWindowSnapshot{displayId:stringx:numbery:numberwidth:numberheight:numberupdatedAt:number}interfaceWindowRestoreDecision{action:RestoreAction layout:LayoutMode reason:string}classWindowBoundaryRestoreGuard{decide(snapshot:WindowSnapshot,displays:DisplayArea[]):WindowRestoreDecision{constdisplaydisplays.find(itemitem.idsnapshot.displayId)if(!display){return{action:recalc,layout:single,reason:外接屏不存在旧窗口坐标不能直接恢复}}constoutOfBoundssnapshot.x0||snapshot.y0||snapshot.xsnapshot.widthdisplay.width||snapshot.ysnapshot.heightdisplay.heightif(outOfBounds){return{action:recalc,layout:display.width1200?double:single,reason:窗口越界先按当前显示区域重算}}return{action:keep,layout:snapshot.width1200?double:single,reason:显示区域存在且窗口未越界可以恢复上次断点}}}constguardnewWindowBoundaryRestoreGuard()console.info(JSON.stringify(guard.decide({displayId:external-1,x:80,y:60,width:1440,height:900,updatedAt:Date.now()},[{id:external-1,width:1920,height:1080}])))console.info(JSON.stringify(guard.decide({displayId:external-1,x:80,y:60,width:1440,height:900,updatedAt:Date.now()},[{id:inner-1,width:1024,height:768}])))这个 Demo 的重点不是炫技而是把问题压到最小一个入口、一个状态变化、一个验证点。先把这个跑通再往复杂页面里搬排查成本会低很多。我会怎么选方案方案适合场景风险继续沿用旧写法旧页面、小范围兼容遇到 7.0 新能力边界时不好排查在页面内临时处理快速验证问题代码容易散后面不好复用抽成独立工具或组件多页面、多设备、多状态复用前期要把输入输出设计清楚我的选择是第三种。只要这个能力会被多个页面用到就不要把判断逻辑塞在页面里。页面只负责展示能力边界、异常兜底、版本判断放到独立函数或组件里。这样后面改 SDK、换设备、补兼容逻辑影响面会小很多。验证清单DevEco Studio 使用支持 HarmonyOS 7.0 / API 26 的版本。真机或模拟器系统版本和文章里的 API 版本一致。至少跑通上面两个场景不只看首屏。如果涉及多设备、窗口、后台恢复要补一次切换测试。如果要发到线上日志里要能看出失败原因而不是只看到一个空状态。最后总结多窗口恢复不能只恢复上一次的宽高。HarmonyOS 7.0 / API 26 场景下应先校验显示区域和窗口边界再恢复页面断点避免外接屏断开后页面错位。这类特性真正有价值的地方不是知道一个新名字而是知道它在什么场景该用、什么时候不该用、怎么复现问题、怎么把修复沉淀成可复用代码。后面再接复杂页面时先把这个小 Demo 跑通基本能避开一半低级返工。再往工程里落一层这里最容易错的点是把窗口快照当成可信数据。窗口快照只能说明上一次怎么显示不能说明这一次还能不能这么显示。外接屏、投屏、分屏、折叠态变化以后先恢复坐标再恢复页面很容易把详情页挂到不可见区域。我会把恢复顺序固定成三步第一步读当前 displays第二步判断 snapshot 是否还在当前显示区域里第三步才决定页面走 single 还是 double。这个顺序比在页面里监听各种变化更稳定因为页面只拿到最终 layout不参与底层判断。输入期望 action期望 layout关键 reason外接屏存在窗口未越界keepdouble可恢复上次断点外接屏不存在recalcsingle旧 displayId 失效显示器存在但窗口越界recalc按当前宽度判断坐标不能照搬宽度低于双栏阈值keep 或 recalcsingle不强塞双栏这类代码适合放进窗口恢复工具层而不是每个页面各写一份。后面适配鸿蒙电脑、多窗口和平板分屏时只要 Guard 输出稳定页面的列表、详情、工具栏都能按同一套 layout 重建。
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门