Web页面也能在窗口间“自由移动”?一文看懂HarmonyOS Web组件窗口迁移
在大屏设备和多窗口场景逐渐普及的今天,应用交互也正在从“单窗口”向更加灵活的多窗口体验延伸。
比如在浏览器类应用中,用户可能希望直接将一个正在浏览的Tab页拖出,变成独立窗口;也可能希望把独立窗口中的页面重新拖回浏览器,与其他Tab页放在一起。如果每次窗口切换都重新创建Web页面,不仅实现起来更加复杂,也难以满足连续、自然的多窗口交互需求。
HarmonyOS Web组件支持在不同窗口的组件树之间进行挂载和移除。开发者可以让同一个Web组件在不同窗口间迁移,实现类似浏览器Tab页拖出、拖入的多窗口交互体验。
为了帮助开发者快速实现HarmonyOS Web组件的窗口迁移,HarmonyOS开发者官网上线了《Web组件在不同的窗口间迁移》最佳实践,只需三步就能让Web页面在窗口间“自由移动”,打造连续、自然的多窗口交互体验。
简单来说,Web组件窗口迁移并不是重新创建一个网页,而是改变已有Web组件在UI组件树中的“位置”。
其基本思路是:首先通过BuilderNode创建Web组件的离线节点,再利用自定义占位节点控制这个Web节点何时挂载、何时移除。当Web节点从窗口A对应的组件树中移除,再挂载到窗口B的组件树中,就完成了一次窗口迁移。
可以把整个过程理解为:创建一个Web组件 → 在窗口A挂载 → 从窗口A移除 → 在窗口B重新挂载。整个迁移过程中,真正发生变化的是Web组件与窗口组件树之间的挂载关系。
要实现窗口迁移,首先需要让Web组件能够脱离固定页面进行动态管理。
在HarmonyOS官方示例中,主窗口Ability启动后,会在loadContent完成之后获取当前窗口的UIContext,并通过命令式方式创建Web动态组件。
具体实现时,需要分别创建WebviewController和BuilderNode。其中,WebviewController负责Web组件相关控制能力,而BuilderNode则负责构建动态组件节点。
开发者还可以通过Map等方式保存对应的BuilderNode和WebviewController,方便后续在不同页面或窗口中获取和管理对应Web组件。
第二步:通过NodeController控制“挂上去”和“拿下来”
组件创建完成后,接下来最关键的就是控制它什么时候出现在窗口中。
这里可以通过继承NodeController实现自定义节点控制逻辑,并借助FrameNode保存当前需要挂载的Web节点。
当需要显示Web组件时,可以获取BuilderNode对应的FrameNode,将其作为当前节点进行挂载;当需要从当前窗口移除Web组件时,则取消对应节点的挂载。
官方示例分别封装了attachWeb()和detachWeb()方法,用来完成Web组件的挂载和移除。
也就是说,开发者不需要围绕每一个窗口重新定义完整Web页面,而是可以围绕同一个Web节点控制其挂载位置。
第三步:利用NodeContainer承载Web节点
有了可动态控制的Web节点之后,还需要在页面中为它准备一个“位置”。
HarmonyOS提供的NodeContainer可以与NodeController配合使用。页面通过NodeContainer绑定对应的NodeController,再通过rebuild()触发节点刷新,最终决定Web组件是否显示在当前页面中。
例如,当用户执行“拖出窗口”操作时,开发者可以先将Web组件从原窗口对应的NodeContainer中移除,再将同一个节点挂载到新窗口对应的NodeContainer。
反过来,当用户需要将独立窗口中的页面重新放回原窗口时,也可以按照相同逻辑重新调整节点挂载关系。
这样一来,窗口迁移就可以从复杂的“页面重新创建”,转化为更加清晰的“节点动态迁移”。
二、一个细节尤其需要注意:同一个Web组件不能“分身”
在实现窗口迁移时,还有一个非常重要的原则:不要将同一个Web组件同时挂载到两个父节点下。
在节点挂载之前,开发者需要判断当前FrameNode是否已经存在父节点。如果Web组件已经挂载在一个窗口的组件树中,就应该先完成移除,再挂载到另一个窗口。
如果同一个Web组件同时被挂载到不同父节点,可能产生非预期行为。官方示例也专门在attachWeb()过程中增加了节点父级检查。
因此,在设计完整的窗口迁移流程时,可以遵循一个简单原则:先移除,再挂载。这也是保证Web组件在不同窗口之间正确迁移的关键。
三、从“页面切换”到“组件迁移”,多窗口体验更灵活
随着PC、平板以及大屏设备上的多窗口使用场景不断丰富,开发者需要考虑的不再只是一个页面如何在一个窗口中展示,也包括内容如何在不同窗口之间灵活流转。
HarmonyOS通过自定义节点、BuilderNode、NodeController和NodeContainer等能力,将Web组件从固定页面结构中解耦出来。开发者可以通过控制节点挂载关系,实现同一个Web组件在不同窗口之间迁移,为浏览器、多窗口办公以及复杂Web应用等场景提供更灵活的实现方式。
对于需要适配多窗口交互的开发者而言,可以重点掌握三个关键点:
▪ 通过BuilderNode创建动态Web节点;
▪ 通过NodeController控制节点挂载和移除
▪ 再通过NodeContainer完成页面承载。
理解这套逻辑之后,Web组件窗口迁移的实现思路也就变得更加清晰。
开发者可访问“HarmonyOS开发者官网”,首页点击“开发”>>“开发文档”,在左侧目录栏找到“开发”,然后依次点击“应用框架”>>“ArkWeb(方舟Web)”>>“管理网页加载与浏览记录”>>“Web组件在不同的窗口间迁移”,查看更详细的示例代码。