导语:折叠屏与平板设备的普及,让"一个应用如何用好一块宽屏"成为开发者绕不开的命题。鸿蒙给出的答案之一,是系统级的平行视界(Easy Go)。它让未做分栏适配的应用也能在宽屏上实现"左列表、右详情"的双页并行。本文基于官方开发文档,梳理平行视界的能力边界、配置体系与适配要点。
平行视界是一种针对大屏设备(折叠屏、平板)的系统级应用显示技术。它打破了传统移动应用只能在单一页面显示的局限,允许同一个应用在屏幕上同时开启两个页面,实现"一级页面左侧显示,二级页面右侧显示"的布局模式。
理解它的关键,在于定位:平行视界是应用在未适配分栏布局的场景下,通过标准化配置实现宽屏、大屏设备分栏显示的系统级兼容方案。 换句话说,它的目标不是替代应用自身精心设计的分栏体验,而是为那些还没来得及做横屏适配的应用,提供一个开箱可用的兜底方案。
开启平行视界并分栏显示时,应用会在一个窗口中同时显示两个页面,默认情况下两页按 1:1 平分窗口。从 API 版本 23 开始,支持开发者自行配置。
它适用于办公、邮箱、IM 即时通讯、电商等需要频繁切换页面的应用类型。
平行视界当前支持两种路由模式,二者的差异直接决定了用户的浏览手感。
导航模式:左侧主页(如商品分类页)保持不变,右侧展示所选分类的商品或具体商品详情,后续相关操作均在右侧进行。它适合办公、邮箱、IM 对话类应用——左侧是稳定的"目录",右侧是流动的"内容"。
购物模式:页面路由跳转时右侧页面始终向左推入,屏幕右侧展示路由栈栈顶页面,左侧展示路由栈次栈顶页面。以购物类应用在双折叠上运行为例,这种"层层深入、随时回退"的推挤式体验,更贴合用户从分类到列表再到详情的连续浏览路径。
不同设备在竖屏和横屏下的默认页面比例如下:
| 设备 | 竖屏 | 横屏 |
|---|---|---|
| 折叠屏展开态 | 左右 1:1 | 左右 1:1 |
| 平板 | 左右 1:1 | 左右 1:1 / 1:2 / 2:1 |
为了增强灵活性,平行视界支持中间分割线拖拽交互,用户可以通过拖动中间的分割杆改变左右页面的比例(如 1:1、1:2 或 2:1)。
平行视界的核心价值在于"双页面并行"。以下是几个典型应用场景:
很多开发者会混淆平行视界与分栏。二者目标体验不同,接入方式也不同,需要根据业务诉求进行选型。
| 对比项 | 平行视界 | 分栏 |
|---|---|---|
| 体验特点 | 为让应用实现横屏适配,提供的系统兜底方案 | 为发挥屏幕横向宽度优势、满足高效操作目标,需应用主动适配 |
| 约束场景 | 基于配置能力接入,能力相对受限,适合希望快速接入分栏体验的应用 | 基于 API 能力接入,功能更完整、控制更灵活,适合对布局体验有精细化定制诉求的应用 |
| 分栏 Pattern | 无固定 Pattern | 左侧列表,右侧详情页 |
| 应用架构 | 导航模式:左侧固定显示首页,右侧显示二级或三级页面;购物模式:左右侧页面可推挤显示 | 父子关系:具有上下级父子关系且层级结构简单,支持侧边栏、双分栏、三分栏,支持自定义栏目布局,建议子页面层级不超过 3 层 |
| 常见业务场景 | 无应用场景的强制约束 | 聊天列表+电话详情、社交关注+动态列表、邮箱列表+邮箱详情、设置分类+设置详情、商品列表+商品详情 |
| 交互操作 | 左右页面比例可调节 | 可通过分栏固定按钮在全屏和分栏间快速切换;左右页面比例可调节 |
一句话总结:平行视界是"配置即得",分栏是"编码可控"。 前者适合快速补齐大屏体验,后者适合深度打磨。
为保证用户体验的一致性,应用在接入时应遵循以下原则:
easy_go.json(示例文件名,可自行命名)。在 module.json5 配置文件中添加 easyGo 字段,并指向引用的 easy_go.json 配置文件。当前仅支持在 entry 模块下配置,配置后应用级生效。easy_go.json 中配置平行视界的相关属性。easy_go.json 是一个标准的 Object 类型 JSON 文件,整体结构分为两层:第一层配置设备类型,第二层配置对应设备类型下的显示模式。
{
"common": {},
"phone": {},
"tablet": {}
}
设备类型(一层配置):
| 字段名 | 说明 | 可选 | 字段类型 |
|---|---|---|---|
| common | 通用设备配置,为所有设备类型提供基础默认配置 | 否 | displayModeOptions |
| phone | phone 类型设备上生效的配置,配置后 common 配置在 phone 类型设备上不再生效 | 是 | displayModeOptions |
| tablet | tablet 类型设备上生效的配置,配置后 common 配置在 tablet 类型设备上不再生效。说明:自由多窗模式下,暂不支持平行视界 | 是 | displayModeOptions |
显示模式(二层配置):displayModeOptions 字段设置平行视界的显示模式,内部字段包括:
| 字段名 | 说明 | 可选 |
|---|---|---|
| wideWindowMode | 控制应用在比直板机宽的长方形宽屏窗口(>= 600vp,宽/高 > 1.2)上的显示方式 | 否 |
| squareWindowMode | 控制应用在比直板机宽的方形宽屏窗口(>= 600vp,高/宽 <= 1.2,宽/高 <= 1.2)上的显示方式 | 是 |
| routerSplitOptions | 平行视界使用 Router 分栏时的配置 | 是 |
| navigationSplitOptions | 平行视界使用 Navigation 分栏时的配置 | 是 |
wideWindowMode / squareWindowMode 的取值含义:
navigationSplit:应用路由由 Navigation 组件实现,必须配合 navigationSplitOptions 一起使用。routerSplit:应用路由由 Router 模块实现,必须配合 routerSplitOptions 一起使用。original:关闭窗口显示模式的兼容运行行为。routerSplitOptions / navigationSplitOptions 内部可包含的字段较多,以下为关键项:
| 字段名 | 说明 | 数据类型 | 可选 |
|---|---|---|---|
| homePage | 主页名称,不配置时系统采用默认策略识别主页 | 字符串 | 是 |
| relatedPage | 关联页名称,不配置时没有关联页能力;必须有 homePage 才能配置 | 字符串 | 是 |
| enableReducedContainerSize | 是否开启虚拟容器能力,默认 false | 布尔值 | 是 |
| fullScreenPages | 支持全屏显示的页面数组,跳转时退出分栏,默认空数组 | 字符串数组 | 是 |
| supportLandscapeFullscreen | 应用主动请求横屏时是否全屏显示,默认 true | 布尔值 | 是 |
| dialogSupportSplit | Dialog 是否支持分栏显示,默认 true | 布尔值 | 是 |
| wideSplit / squareSplit | 长方形/方形窗口上的配置参数,含 ratio、isDraggable,从 API 26.0.0 开始支持 | 对象 | 是 |
| mode | 路由模式,默认 1。0 为购物模式,1 为导航模式,从 API 26.0.0 开始支持 | 数值 | 是 |
| pagePairs | 页面跳转关系对,仅在导航模式下生效,从 API 26.0.0 开始支持 | 对象数组 | 是 |
| transPages | 过渡页面,购物模式下生效,固定在右侧显示,从 API 26.0.0 开始支持 | 字符串数组 | 是 |
| splitDividerColor | 分割线颜色,支持深浅色模式,从 API 26.0.0 开始支持 | 对象 | 是 |
| drawableRectHook | WindowProperties.drawableRect 是否开启页面级容器能力,默认 false,从 API 26.0.0 开始支持 | 布尔值 | 是 |
| enableInSplitScreen | 是否支持在窗口分屏场景进入平行视界,默认 false,从 API 26.0.0 开始支持 | 布尔值 | 是 |
navigationSplitOptions 还可额外包含 homeNavigationId、disablePlaceholder、disableDivider 等字段。
wideSplit / squareSplit 内部字段:
ratio:左右页面比例,格式为"正整数 | 正整数",范围限制在 1:2 到 2:1 之间,未配置时默认 1:1,超出范围时取边界值。isDraggable:是否开启分栏拖拽,默认 false。开启后 ratio 字段失效,默认 1:1,使用三档吸附,可在 1:2、1:1 和 2:1 之间拖动。routerSplitOptions 和 navigationSplitOptions 不能同时存在。light 和 dark 为相同颜色。Router 路由下为通用设备配置平行视界:
{
"common": {
"displayModeOptions": {
"wideWindowMode": "routerSplit",
"squareWindowMode": "routerSplit",
"routerSplitOptions": {
"homePage": "pages/Index",
"relatedPage": "pages/CategoryPage",
"fullScreenPages": ["pages/FullScreenImagePage"],
"supportLandscapeFullscreen": true,
"enableReducedContainerSize": true
}
}
}
}
Navigation 路由下为通用设备配置平行视界(平板/三折叠长方形窗口设 1:2,双折叠方形窗口设 1:1):
{
"common": {
"displayModeOptions": {
"wideWindowMode": "navigationSplit",
"squareWindowMode": "navigationSplit",
"navigationSplitOptions": {
"homePage": "navBar",
"relatedPage": "CategoryPage",
"fullScreenPages": ["FullScreenImagePage"],
"supportLandscapeFullscreen": true,
"enableReducedContainerSize": true,
"wideSplit": { "ratio": "1 | 2" },
"squareSplit": { "ratio": "1 | 1" },
"mode": 0,
"splitDividerColor": {
"light": "#33FFFFFF",
"dark": "#33000000"
},
"drawableRectHook": true,
"enableInSplitScreen": true
}
}
}
}
为 tablet 设备单独关闭平行视界:
{
"common": {
"displayModeOptions": {
"wideWindowMode": "navigationSplit",
"squareWindowMode": "navigationSplit",
"navigationSplitOptions": {
"homePage": "CategoryPage",
"fullScreenPages": ["FullScreenImagePage"],
"supportLandscapeFullscreen": true,
"enableReducedContainerSize": false
}
}
},
"tablet": {
"displayModeOptions": {
"wideWindowMode": "original",
"squareWindowMode": "original"
}
}
}
以 Navigation 路由实现的购物类应用为载体,官方文档梳理了七个高频场景。
场景一:配置主页与关联页。 系统默认的主页识别机制在部分场景下不够准确,建议主动配置。通过 homePage 设置主页(如 "navBar" 表示 Navigation 首页),通过 relatedPage 设置关联页(如 "CategoryPage")。
场景二:配置路由模式。 购物类应用浏览路径层层深入,购物模式更贴合体验。通过 mode 字段设置,0 为购物模式。
场景三:设置过渡页面。 地址编辑页等临时编辑操作页面,固定在右侧显示、左侧分栏内容保持不变,交互更连贯。通过 transPages 配置。
场景四:路由跳转过程请求全屏。 商品详情页点击图片需全屏展示时,通过 fullScreenPages 指定全屏页。配置后对应页面展示时暂时退出分栏,页面隐藏时恢复分栏。
场景五:路由跳转过程请求横屏显示。 "参数对比""配置表"类图片需要横屏展示时,将 supportLandscapeFullscreen 设为 true,应用请求横屏时会退出分栏、全屏展示。
场景六:开启虚拟容器能力。 分栏时两页默认 1:1 平分窗口,若页面元素布局使用窗口宽度,可能导致 UI 元素超出范围被截断。将 enableReducedContainerSize 设为 true 后,lpx 单位、横向断点、窗口宽度尺寸和屏幕宽度尺寸将使用原始尺寸的一半进行计算。
场景七:平行视界场景下触发应用内分屏。 在平板或三折叠三屏态(G 态)等大屏设备上,用户希望一边浏览商品详情一边比价、查物流。将 enableInSplitScreen 设为 true 后,应用进入窗口分屏时若宽高满足条件,则继续保持平行视界分栏显示。实现上需要在商品详情页顶部添加分屏按钮,通过 isEasySplit() 判断是否处于分栏态、通过 windowStatusType 判断是否已分屏,仅在分栏态且未分屏时显示按钮;点击后调用 startAbility() 拉起应用新实例,并指定窗口分屏模式及主窗口占比。
private startSplitScreen(): void {
try {
const context = this.getUIContext().getHostContext() as common.UIAbilityContext;
context.startAbility(
{
bundleName: CommonConstants.BUNDLE_NAME,
abilityName: 'EntryAbility',
},
{
windowMode: AbilityConstant.WindowMode.WINDOW_MODE_SPLIT_PRIMARY,
splitRatio: window.SplitRatioPreference.PRIMARY_DOMINANT
}
).then(() => {
hilog.info(0x0000, 'testTag', 'Succeeded in starting split screen mode.');
}).catch((err: BusinessError) => {
hilog.error(0x0000, 'testTag',
`Failed to start split screen mode. Code:${err.code}, message:${err.message}`);
});
} catch (error) {
let err = error as BusinessError;
hilog.error(0x0000, 'testTag',
`Failed to start split screen mode. Code:${err.code}, message:${err.message}`);
}
}
问题一:UI 元素超出页面范围被截断。 原因是分栏时两页 1:1 平分窗口,而页面元素布局使用了窗口宽度。解决方案有三:优先使用系统组件的自适应布局能力;开启虚拟容器能力(enableReducedContainerSize 设为 true);使用页面大小获取接口和无感监听能力,如 on('navDestinationUpdate')、on('routerPageUpdate')、onRouterPageSizeChange()、onNavDestinationSizeChange()。
问题二:组件复用场景下同一资源只在一个页面中显示。 原因是左右分栏页面利用 ArkUI 组件复用机制(如 NodeContainer)共用了同一个 UI 资源。建议改为两边页面使用独立的 UI 资源,互不影响。
问题三:使用页面级窗口策略不生效。 平行视界场景下会同时显示左右两个页面,两个页面方向需要一致,因此 NavDestination 组件的 preferredOrientation 属性不生效。推荐使用窗口级方案,通过 window 提供的 setPreferredOrientation() 接口设置。
问题四:一镜到底等转场效果不生效。 应用接入平行视界后,系统会屏蔽或修改部分场景动效:Router 类型的平行视界会屏蔽所有自定义转场;Navigation 类型在主页首次跳转到二级页面或二级页面返回首页时会屏蔽所有转场,默认无动画跳转;购物模式下会屏蔽自定义转场,默认右推左或左推右实现平移转场。建议在这些场景下关闭自定义转场,遵循系统默认效果。
问题五:运行时无法仅通过配置预知分栏模式。 分栏模式由配置和设备窗口形态共同决定,运行中窗口大小变化、分屏等操作都可能导致模式切换。解决方案是通过 UIContext 提供的 isEasySplit() 接口在运行时查询,该接口从 API 版本 24 开始支持,返回 boolean 值:true 表示处于分栏模式,false 表示未处于分栏模式。
从平行视界的配置体系演进可以读出几个信号。
第一,配置能力正在快速补齐。 从 API 23 支持自配置,到 API 26.0.0 一次性引入 mode、pagePairs、transPages、splitDividerColor、drawableRectHook、enableInSplitScreen 等一批字段,平行视界从"能分栏"走向"分得好"。购物模式、过渡页面、分屏内保持分栏这些能力,说明系统层正在把过去需要应用自己编码实现的体验,逐步下沉为声明式配置。
第二,兜底方案与精细定制的边界更明确。 官方在对比表中明确:平行视界是"系统兜底方案",分栏是"应用主动适配"。这意味着对于体验要求高的头部应用,分栏仍是更优解;而对于长尾应用,平行视界是低成本补齐大屏体验的现实路径。二者不是替代关系,而是分层关系。
第三,适配成本的重心从"写代码"转向"调配置 + 处理边界"。 从五个常见问题可以看出,真正的坑集中在 UI 自适应、资源复用、转场动效、运行时状态判断这些细节上。开发者需要建立"分栏态是一种动态状态"的认知,善用 isEasySplit() 等运行时接口,而不是假设配置即终态。
平行视界为开发者提供了一种高效、标准化的系统级兼容方案,使未适配分栏布局的应用能够在大屏设备上获得双页面并行的体验。通过合理配置,开发者可以灵活控制路由模式、主页与关联页、全屏页、虚拟容器等能力,满足不同业务场景的需求。
在适配过程中,需注意 UI 元素自适应、资源复用、转场效果等常见问题,并遵循逻辑一致性、不改变原有交互、信息密度适中这三条接入原则,以确保用户体验的一致性。对于正在布局折叠屏与平板生态的鸿蒙应用而言,平行视界是投入产出比相当高的一步——它未必是终点,但足以让应用在大屏上"先站住"。
配图建议:可插入一张折叠屏展开态下"左列表、右详情"的平行视界分栏示意图,以及一张 easy_go.json 两层配置结构的示意图,帮助读者建立直观认知。
生成标记:本文由 ITPUB 文章生成平台基于已选素材整理生成。
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/69965512/viewspace-3185589/ ,如需转载,请注明出处,否则将追究法律责任。