本文基于 HarmonyOS 7(API 26)官方《平行视界》能力介绍与开发指导整理。文中代码是为说明问题自写的完整示例,不是官方示例的搬运;配置文件字段名、枚举值等事实性信息均标注官方出处,未能逐字核实的指向写法已注明"以官方文档为准";涉及真机表现的部分以真机实测为准,未做任何实测数据编造。
引子:折叠屏展开的那一刻,你的应用在"整页跳"
V哥有个习惯,拿到新折叠屏先装自己团队的电商 Demo。展开态下点一个商品,整页跳转;再点推荐商品,又整页跳转。十二英寸的屏幕,利用率不到一半,旁边全是黑边和留白。同事说了句扎心的:"这应用是把平板当大号手机用。"
传统解法是重写导航:把 Router 迁到 Navigation、把页面塞进双分栏布局、把状态同步逻辑推倒重来。对多数业务团队来说,这是一场伤筋动骨的重构。
HarmonyOS 7(API 26)把另一条路铺好了:平行视界 EasyGo 能力升级,开发者不改业务代码,写一份配置文件就能让应用在大屏上以左右双页的方式运行,路由模式、分栏比例、分割线样式全部可配(官方新能力一览)。这期V哥把它拆开讲:机制、配置、路由模式、比例与分割线、应用内分屏,最后给一份"该不该用平行视界"的选型判断。
一、先摆正定位:平行视界是系统级兜底,不是新框架
官方的定义很克制(平行视界能力介绍):
平行视界是一种针对大屏设备(折叠屏、平板)开发的系统级应用显示技术。它打破了传统移动应用只能在单一页面显示的局限,允许同一个应用在屏幕上同时开启两个页面,实现"一级页面左侧显示,二级页面右侧显示"的布局模式。
V哥从这段话里读出三个重点:
| 重点 | 意思 | 对开发者的直接影响 |
|---|---|---|
| 系统级 | 分栏由系统按路由栈自动完成,不进你的页面代码 | 老业务零改动,只写配置 |
| 兼容方案 | 官方原话:针对"未适配分栏布局"场景的系统兜底方案 | 定位是快速接入,不是精细定制 |
| 自配置从 API 23 起 | SDK 6.1.0(23) 即支持开发者自配置;路由模式、比例、分割线等为 API 26 新增 | 老版本只能吃默认 1:1,7.0 才有完整的"随意切" |
第三条要特别标注:路由模式、分栏比例拖拽、分割线颜色这些 7.0 的新能力,需升级至 HarmonyOS 7 并以实际支持机型为准,具体表现以真机实测为准。
还有一条硬边界:自由多窗模式下,暂不支持平行视界(官方说明,针对 tablet 设备配置项)。做窗口化场景的应用要先确认自己的主战场。
二、接入三步:一份 JSON、一行注册、应用级生效
官方把物理形态规定得很简单(平行视界开发指导):在 profile 目录下创建配置文件(官方示例名 easy_go.json,可自行命名),在 module.json5 中添加 easyGo 字段指向它。当前仅支持在 entry 模块下配置,配置后应用级生效。指向写法的细节以官方文档"开发步骤"一节为准,这里写结构示意:
{
"module": {
// V哥注:easyGo 字段指向 profile 目录下的 easy_go.json(文件名可自行命名),
// 具体指向写法以官方文档《平行视界》开发指导"开发步骤"一节为准
"easyGo": "$profile:easy_go"
}
}
easy_go.json 是标准的两层 JSON(字段名均已按官方文档核实):
{
"common": {
"displayModeOptions": {
// 长方形宽屏窗口(>=600vp 且宽/高 > 1.2):走 Navigation 分栏
"wideWindowMode": "navigationSplit",
// 方形宽屏窗口(>=600vp 且高/宽、宽/高均 <= 1.2):同上
"squareWindowMode": "navigationSplit",
"navigationSplitOptions": {
"homePage": "navBar", // Navigation 首页做主页;用 NavDestination 做主页则配其 name
"relatedPage": "CategoryPage", // 启动关联页:冷启动直接进列表
"mode": 0, // 0=购物模式(左右推挤),1=导航模式(固定覆盖),默认 1
"wideSplit": { "ratio": "1 | 2" }, // 长方形窗口默认 1:2
"squareSplit": { "ratio": "1 | 1", "isDraggable": true }, // 方形窗口开拖拽,三档吸附
"transPages": ["AddressEditPage"], // 过渡页固定右侧,不被推挤
"fullScreenPages": ["FullScreenImagePage"], // 进此页退出分栏,返回恢复
"splitDividerColor": { // 分割线颜色,深浅色模式分开配
"light": "#33FFFFFF",
"dark": "#33000000"
},
"enableInSplitScreen": true, // 窗口分屏下宽高满足条件则保持平行视界
"enableReducedContainerSize": true // 虚拟容器:断点/宽度按右侧页面尺寸计算
}
}
},
"tablet": {
"displayModeOptions": {
"wideWindowMode": "original", // 在 tablet 上单独关掉兼容行为
"squareWindowMode": "original"
}
}
}
第一层是设备类型:common 提供默认配置,phone/tablet 单独配置后覆盖 common。第二层 displayModeOptions 里,wideWindowMode/squareWindowMode 取三个枚举值:navigationSplit(路由由 Navigation 实现)、routerSplit(路由由 Router 实现)、original(关闭兼容行为)。注意 routerSplitOptions 和 navigationSplitOptions 不能同时存在,官方明确不建议在启用平行视界的应用里混用两种路由框架。
V哥最想强调的是 homePage:对 Navigation 路由,首页配 "navBar";如果想让某个 NavDestination 当主页,就配它的 name。官方建议主动配置主页——默认的主页识别机制"在有些场景下不能准确识别",识别错了,分栏的左右关系就全乱了。
三、路由模式:mode 0 和 mode 1,两种"左右"哲学
API 26 新增的 mode 字段是这期升级的核心。两种模式对应两种浏览心智(两种模式的交互规则均引自官方能力介绍):
购物模式(mode: 0)——左右推挤。页面路由跳转时右侧页面始终向左推入,屏幕右侧展示路由栈栈顶页面,左侧展示次栈顶。左侧点商品、右侧出详情;在右侧再点推荐商品,原页面左移、新页面右推。适合"层层深入、随时回退"的浏览流:商品详情、机酒比价、内容连续浏览。临时编辑类页面(如地址编辑)用 transPages 固定在右侧,不被推挤。
导航模式(mode: 1,默认)——固定覆盖。左侧主页保持不变,右侧内容区以覆盖形式切换:左侧点条目,新页面覆盖右侧;右侧点条目,同样覆盖右侧;触发全局返回时,右侧回到上一层级。适合"导航固定、内容切换"的场景:IM 聊天、邮箱、长文阅读、分类导航。
还有个精细控件 pagePairs:配置 {from, to} 跳转关系对,仅在导航模式下生效——从 from 跳 to 时触发分栏,from 在左、to 在右,to 还可以配 "*" 表示任意页面。V哥的理解:mode 是全局的哲学,pagePairs 是对个别入口的精修,两者配合可以做到"全局导航式,个别入口比价式"。
四、比例与分割线:1:2/2:1 预设 + 三档吸附拖拽
这就是标题里"1:2/2:1 随意切"的出处。API 26 在 navigationSplitOptions(或 routerSplitOptions)里新增了 wideSplit 和 squareSplit 两个对象,内部两个字段:
ratio:左右页面比例,格式为"正整数 | 正整数",范围限制在 1:2 到 2:1 之间,未配置默认 1:1,配超了取范围边界值。V哥的写法习惯:平板这类长方形窗口配"1 | 2"让详情占主视野,双折叠的方形展开态配"1 | 1"。isDraggable:开拖拽后ratio失效,默认从 1:1 起,三档吸附——在 1:2、1:1、2:1 之间可以拖动。用户自己找到舒服的比例,比开发者猜更聪明。
分割线也有两个开关:splitDividerColor 配深浅色两种颜色(十六进制 #AARRGGBB,官方提醒:应用不适配深色模式时,light 和 dark 配成同色);navigationSplitOptions 独有的 disableDivider 可以干脆隐藏分割线。
配套还有一批"防止左右页打架"的字段,V哥按官方说明列个速查表:
| 字段 | 作用 | V哥的用法建议 |
|---|---|---|
fullScreenPages | 进入即退出分栏,返回恢复 | 图片全屏、视频播放页必配 |
supportLandscapeFullscreen | 主动请求横屏时退出分栏(默认 true) | 参数对比大表类页面 |
dialogSupportSplit | 弹窗在右半屏显示(默认 true) | 默认即可,想居中再关 |
enableReducedContainerSize | 断点/lpx/窗口宽度按右页尺寸计算 | 强烈建议开,治 UI 截断的头号药方 |
drawableRectHook | Window.drawableRect 按右页尺寸计算 | 与上一条配套 |
官方"常见问题"第一条就是 UI 元素被截断——窗口一半宽度装原来的布局,元素当然溢出。除了虚拟容器,官方还给了 on('navDestinationUpdate')、onNavDestinationSizeChange() 等监听接口(API 23+)拿页面真实尺寸。V哥的顺序建议:自适应布局优先,虚拟容器兜底,监听接口留给精细场景。
五、应用内分屏:分屏入口 + 一段 ArkTS
7.0 还有一层组合技:应用处于平行视界分栏时,用户点详情页顶部的分屏入口,应用以主窗口形式进入系统窗口分屏,且原窗口继续保持平行视界效果——左边列表加详情,右边再开比价或物流查询,一屏三区(论坛官方解读)。
接入分两步。第一步配置 enableInSplitScreen: true(默认 false,不配就永远不进)。第二步在详情页加按钮,官方给的判断逻辑和拉起方式,V哥按自己的注释习惯整理:
// GoodsDetailPage.ets —— 分屏入口:只在"分栏态 + 未分屏"时露出
import { common, AbilityConstant } from '@kit.AbilityKit';
import { window } from '@kit.ArkUI';
// 按钮可见性:isEasySplit() 判断是否处于平行视界分栏态,
// windowStatusType 判断是否已处于窗口分屏
Button($r('app.string.enter_split'))
.visibility(this.getUIContext().isEasySplit() &&
this.mainWindowInfo.windowStatusType !== window.WindowStatusType.SPLIT_SCREEN
? Visibility.Visible : Visibility.None)
.onClick(() => this.startSplitScreen())
// 拉起应用新实例,指定主窗口占比,以主窗口形式进入系统分屏
private startSplitScreen(): void {
const context = this.getUIContext().getHostContext() as common.UIAbilityContext;
context.startAbility(
{ bundleName: 'com.vge.demo', abilityName: 'EntryAbility' },
{
windowMode: AbilityConstant.WindowMode.WINDOW_MODE_SPLIT_PRIMARY,
splitRatio: window.SplitRatioPreference.PRIMARY_DOMINANT
});
}
接口名(isEasySplit()、WindowStatusType.SPLIT_SCREEN、WINDOW_MODE_SPLIT_PRIMARY、SplitRatioPreference.PRIMARY_DOMINANT)均出自官方开发指导的示例代码。实际分屏效果以真机实测为准。
六、V哥的判断:什么时候用平行视界,什么时候老老实实写 Navigation
第一期讲一多布局时V哥写过定位:平行视界不替代 Navigation,它是"列表-详情"高频场景的系统级捷径。官方能力介绍里有一张"平行视界与分栏体验对比"表,V哥把结论翻译成大白话:分栏(Navigation 一多)是主动适配,功能完整、控制灵活,适合对布局有精细化定制诉求的应用;平行视界是配置接入,能力相对受限,适合想快速拿到分栏体验的应用。
据此V哥给三条选型判断:
① 页面关系是"路由栈",就用平行视界。 左右页天然是父层级到子层级、用户预期就是"左点右出",电商详情、IM 聊天、邮箱正文——一份 JSON 解决,何必重写。这也是官方列的典型价值场景:购物对比、即时通讯、内容消费、邮件办公。
② 布局要"长成设计稿",就自己写 Navigation。 需要侧边栏、三分栏、跨栏联动、特殊转场、复杂状态同步的,平行视界的固定双页给不了,老老实实用 Navigation 的分栏能力,子页面层级官方建议不超过三层。
③ 两者可以分设备共存。 tablet 层配 original 关掉平行视界、让平板走你自己的 Navigation 分栏;common 留着兼容手机投宽屏、折叠屏这些你顾不上的形态。大屏体验一步到位是理想,配置兜底是现实,先用现实接住用户,再奔理想。
参考与出处
本文涉及的机制、字段与交互规则来自以下官方材料,均为V哥动笔前逐条核验的原文出处:
- 平行视界开发指导(最佳实践)
- 平行视界能力介绍(设计指南)
- HarmonyOS 7(API 26)新能力解读:平行视界开启大屏多任务新体验(官方论坛)
- HarmonyOS 新能力一览(7 / API 26)
最后一句:大屏适配的尽头不一定是重构——把路由栈交给系统,把设计稿留给自己,一份 easy_go.json 写对 homePage 和 mode,折叠屏展开的那一秒,你的应用就从"大号手机"变成了"两个页面各得其所"。