智绘鸿蒙 · 如 7 而至端侧 AI 能力实战手记

平行视界在哪些设备上真的会分栏:三台鸿蒙 7 真机实测

智绘鸿蒙·如 7 而至

前言

平行视界这个能力,官方文档写得挺清楚,但我按文档配完之后,在自己手上三台鸿蒙 7 设备上,只有一台分了栏

另外两台无论怎么改配置都没反应,也不报错,应用照常运行,只是不分栏。

后来才搞明白:生效条件里"窗口尺寸够大"只是必要条件,设备形态这一条文档写得很靠后、而且很容易看漏

所以这篇就把这件事讲清楚:哪些设备真的会分栏、配置文件怎么写才不被 schema 打回来、以及鸿蒙 7(API 26)到底新在哪。

平行视界是什么

一个系统级兼容方案:应用不改路由代码,只加一份配置,就能在宽屏窗口里同时显示两个页面——主页在左,关联页在右。

通俗地理解:它替你给"没做过大屏适配"的存量应用兜了个底。

官方给的适用场景是办公、邮箱、IM 即时通讯、电商这类需要频繁在列表和详情之间切换的应用。我拿一个行情类应用「盘面随行」做载体(左自选列表、右行情详情),效果和官方描述一致。

先说不适合的情况:如果是新应用、又要求精细的宽屏体验,应该直接用 Navigation + NavigationMode.Split 自己做分栏适配,而不是让系统替你猜哪个页面该放左边。文档把它归在"兼容方案"目录下,这个定位不是随便写的。

触发条件

配置项 wideWindowMode 的生效前提,原文是这样:

控制应用在**比直板机宽的长方形宽屏窗口(>= 600vp,宽/高 > 1.2)**上的显示方式。

还有一个 squareWindowMode,对应方形宽屏窗口(>= 600vp,高/宽 <= 1.2 且 宽/高 <= 1.2),主要用于三折叠的 G 态、双折叠展开态。

  • vp:virtualPixel,鸿蒙的虚拟像素单位,与设备物理像素的换算关系是 vp = px / densityPixels
  • 分栏比例:左右两栏的宽度比,API 26 起可配置,范围 1:2 到 2:1。
  • 自由多窗:一种多窗口显示模式,允许同屏运行多个应用窗口。PC 形态默认就是它。

三台真机的实测矩阵

我把满足条件的窗口尺寸在三台设备上分别跑了一遍。设备都是 HarmonyOS 7.0.0.x、API 26:

设备 形态 窗口 尺寸(vp) 宽/高 分栏
MatePad Pro (MRDI-W00) tablet 横屏全屏 1318×866 1.52
MatePad Pro tablet 竖屏全屏 866×1318 0.66
MateBook Pro (HAD-W32) 2in1 自由多窗 1228×788 1.56
MateBook Pro 2in1 点最大化 1470×788 1.87
Mate 70 Pro (PLR-AL00) phone 强制横屏 809×376 2.15

三个结论:

第一,竖屏平板不分栏。 866×1318 vp,宽高比 0.66,两个模式的条件都不满足。竖屏平板想要分栏,得应用自己做布局。

第二,PC(2in1)不分栏,而且是设计如此。 官方文档在 tablet 配置项下注明了一句:"自由多窗模式下,暂不支持平行视界。" PC 的应用窗口就是自由多窗形态。

我试过用 supportWindowMode: ["fullscreen"] 把 ability 限制成只支持全屏来绕开,结果应用启动即退出,日志:

WMSDecor: GetTitleButtonVisible: isMaximizeVisible param INVALID
WMSDecor: GetTitleButtonVisible: isSplitVisible param INVALID

这条路走不通,别浪费时间。

第三,直板机横屏不算"比直板机宽"。 Mate 70 Pro 横屏是 809×376 vp,数值上完全满足 ≥600vp 和宽高比 >1.2,但系统不认——判定看的是设备形态,不是当前窗口朝向。

所以结论很直白:要演示平行视界,你需要一台平板(横屏)或者折叠/三折叠屏。

配置文件怎么写

第一步:module.json5 声明入口

easyGo 字段加在 module 层级,目前只支持在 entry 模块下配置,配置后应用级生效:

{
  "module": {
    "name": "entry",
    "type": "entry",
    "pages": "$profile:main_pages",
    "easyGo": "$profile:easy_go",
    "abilities": [ /* … */ ]
  }
}

第二步:写 easy_go.json

文件必须放在 resources/base/profile/ 目录下,文件名可以自定义。下面是我最终跑通的版本(Router 路由 + 1:2 分栏 + 自定义分割线):

{
  "common": {
    "displayModeOptions": {
      "wideWindowMode": "routerSplit",
      "routerSplitOptions": {
        "homePage": "pages/Index",
        "relatedPage": "pages/StockDetail",
        "mode": 1,
        "wideSplit": { "ratio": "1 | 2" },
        "splitDividerColor": { "light": "#FF3B6BFF", "dark": "#FF7A9BFF" },
        "supportLandscapeFullscreen": false,
        "enableInSplitScreen": true
      }
    }
  }
}

结构是两层:第一层设备类型(common / phone / tablet),第二层显示模式(displayModeOptionssettingDisplayOptions,两者互斥)。

四个 schema 硬约束

hvigor 会按 SDK 里的 schema 校验这个文件,违反就直接中断构建:

hvigor ERROR: 00303038 Configuration Error
Error Message: Schema validate failed, at file: .../resources/base/profile/easy_go.json

四条我全踩过的规则:

约束 正确写法 容易写成
ratio 格式 "1 | 2"(竖线两侧带空格) "1:2"
ratioisDraggable 互斥,isDraggable: true 时不能出现 ratio 两个都写
splitDividerColor 8 位十六进制 #AARRGGBB 6 位 #3B6BFF
relatedPage 必须先有 homePage 只配 relatedPage

补充两点:routerSplitOptionsnavigationSplitOptions 不能同时存在;ratio 超出 1:2 ~ 2:1 范围时会自动取边界值。

文档正文里写的是"数据格式为正整数 | 正整数",很容易看成冒号比——我第一次就栽在这。

第三步:横屏也要保持分栏

如果应用通过 ability 的 orientation: "landscape" 主动请求横屏,必须同时把 supportLandscapeFullscreen 设为 false,否则横屏时会退出分栏改成全屏显示。本文所有截图都是这个组合下拿到的。

HarmonyOS 7 新增了什么

平行视界的自配置能力从 API 23 就有了。API 26(鸿蒙 7)新增的是下面这几个标签,我逐个实测过:

字段 作用 实测
wideSplit / squareSplit 分别控制长方形/方形宽屏窗口的分栏参数 生效
wideSplit.ratio 左右比例,1:2 ~ 2:1 列表被压到 933/2800 px
wideSplit.isDraggable 三档吸附拖拽 拖后吸附到 2:1
mode 0 购物模式 / 1 导航模式 见下节
pagePairs 精确指定哪些 from→to 才触发分栏 未单独验证
transPages 购物模式下固定在右栏的过渡页 未单独验证
splitDividerColor 分割线颜色,支持深浅色 蓝线可见
enableInSplitScreen 窗口分屏场景下也进入平行视界 生效
drawableRectHook drawableRect 按右栏尺寸计算 未单独验证

换句话说,"能不能自定义分栏比例、能不能拖拽、能不能指定路由模式和分割线颜色"就是鸿蒙 7 前后的分水岭。在那之前只能配主页、关联页和全屏页,比例固定 1:1,分割线跟着系统色。

导航模式与购物模式

mode: 1(导航模式):左栏主页始终不动,右栏承载关联页及其后续操作。适合"列表 → 详情 → 详情内动作"这种单向流程。我的盘面随行就是这个模式,点任何股票,左栏列表都在。

mode: 0(购物模式):页面路由跳转时右侧页面持续向左推入,右栏永远是路由栈栈顶,左栏是次栈顶。适合层层深入又需要频繁回退的流程。

有些页面就是不该塞进右栏

右栏只占窗口 2/3。长表格、参数对比图、全屏行情图、富文本编辑器放进去必然变形。fullScreenPages 就是给这些页面开的口子——跳到数组里声明的页面时自动退出分栏,铺满整个窗口

"fullScreenPages": [
  "pages/NotesPage"
]

页面铺满了 2800px 全宽,左栏列表消失,返回后分栏自动恢复。

注意约束:fullScreenPages 里的页面不能和 homePagerelatedPage 重复(transPages 同理)。

怎么排查"配置到底生效没有"

平行视界最难查的地方在于:配置写错了没有任何提示。我用三步定位法,能区分"配置没打进包""打进去了但形态不允许""配置和形态都没问题"。

第一步,确认产物里有两个文件。

unzip -p entry/build/default/outputs/default/entry-default-signed.hap module.json
unzip -l entry/build/default/outputs/default/entry-default-signed.hap | grep easy

前一条要能看到 "easyGo": "$profile:easy_go",后一条要能看到 resources/base/profile/easy_go.json。少任意一个,说明引用路径或文件位置不对,后面不用查了。

第二步,确认窗口形态。 执行 devecocli ui layout,看根节点下有没有 DecorBar#ContainerModalTitleRow

  • 有(还带 EnhanceMaximizeBtn / EnhanceMinimizeBtn / EnhanceCloseBtn)→ 自由多窗形态,平行视界不会生效
  • 没有,根节点直接是 WindowSceneStack#ContainerModalStack → 全屏形态,具备生效条件

这条判据在 PC 和平板上验证过,很准。

第三步,用尺寸反推。devecocli ui layout 输出的根节点像素宽高除以密度(hidumper -s DisplayManagerService -a -a 里的 Density),得到 vp,再对照 600vp 和 1.2 两条线。上面那张矩阵就是这么算出来的。

三步走完还不分栏,才需要考虑设备形态本身被排除(直板机、2in1)。

总结

什么场景值得开平行视界:存量应用(页面已经是一堆 Router 跳转)、用户里有平板或折叠屏、又不想为宽屏重做布局——加一份配置就得到分栏体验,成本几乎为零。办公、邮箱、IM、电商、行情这类"列表 + 详情"来回跳的应用最典型。

反过来,新应用要做精细宽屏体验,直接用 Navigation + NavigationMode.Split 自己适配;只有直板机或鸿蒙 PC 的话,这个能力暂时帮不上你。

💡 一句话:先拿平板横屏验证能不能分栏,再来调配置——生效与否取决于设备形态和窗口模式,不是窗口尺寸。

参考文献

  1. 最佳实践 · 多设备界面开发 / 兼容方案 / 平行视界:https://developer.huawei.com/consumer/cn/doc/best-practices/bpta-easygo-parallel
  2. HarmonyOS 7(API 26) 官方新能力解读 & 开发者实战开发案例合集:https://developer.huawei.com/consumer/cn/forum/topic/0208224160644765091