第7.13篇:平行视界 EasyGo 与应用内分屏

难度:⭐⭐ 进阶
前置知识:第 5.7 篇 多设备形态适配
涉及源文件:参考 UI Design Kit 文档


概述

在 HarmonyOS 7(API 26)中,多窗口交互体系迎来了两项重要能力:平行视界 EasyGo应用内分屏(In-App Split Screen)。前者是系统级的应用分屏启动框架,后者是应用开发者可控的页面级分屏 API。两者共同构成了鸿蒙在大屏设备上的"高效多任务"技术底座。

对于"画伴梦工厂"这样的创作类应用而言,这些能力尤为重要——用户可能需要在画布上绘画的同时查看参考图、在编辑作品时对比前后版本、或者在 AI 生成等待期间浏览其他内容。传统的全屏页面切换模式在这些场景下效率低下,而平行视界 EasyGo 与应用内分屏则提供了全新的交互维度。

本文将系统性地解析这两项能力的设计理念、API 模型、配置方式,并结合"画伴梦工厂"的创作场景探讨其落地路径。


一、平行视界 EasyGo——应用级分屏启动框架

1.1 什么是平行视界 EasyGo?

平行视界(Parallel Vision)是 HarmonyOS 在大屏设备(平板、折叠屏、2in1)上的分屏交互体系。其核心思想是:同一个应用可以在屏幕上同时展示两个页面,左边是总览/导航,右边是详情/内容。

在 HarmonyOS 7 之前,平行视界更多是系统级的自动适配行为——应用无需做任何配置,系统在横屏下自动将页面拆分为左右两栏。但这种"一刀切"的方式存在明显局限:

  • 应用无法控制分屏的比例和模式
  • 无法选择哪些页面可以并排显示
  • 无法在分屏中嵌入自定义交互

EasyGo 正是为了解决这些问题而生的。它是平行视界在 HarmonyOS 7 中的升级版本,提供了一组声明式配置 API,让应用开发者能够精确控制分屏的启动方式、显示比例、交互模式。

1.2 EasyGo 的核心能力

能力 说明 适用场景
1:2 启动 左侧 1/3、右侧 2/3 的分屏比例 列表+详情模式
2:1 启动 左侧 2/3、右侧 1/3 的分屏比例 主画布+辅助面板模式
购物模式 左右联动滚动,商品列表与详情同屏显示 电商价格对比
导航模式 左侧地图总览、右侧路线详情 导航场景
配置式接入 通过 JSON 或代码声明分屏行为 所有场景

1.3 EasyGo 四种模式详解

1:2 比例模式

这是最常用的分屏比例,适用于"总览 + 详情"的场景:

┌──────────┬──────────────────────────┐
│          │                          │
│  列表     │        详情              │
│  1/3     │        2/3               │
│          │                          │
└──────────┴──────────────────────────┘
// 启动一个 1:2 比例的平行视界
// 左侧 pages/ItemList,右侧 pages/ItemDetail
import { parallelVision } from '@kit.KernelKit';

parallelVision.startEasyGo({
  leftPage: 'pages/ItemList',
  rightPage: 'pages/ItemDetail',
  ratio: '1:2',            // 左右比例
  linkType: 'detail',      // 联动类型:列表→详情
  params: {
    categoryId: 'all',
    fromEasyGo: true       // 标记来自 EasyGo,便于页面做适配
  }
});

2:1 比例模式

当主操作区域需要更大空间时使用,适用于"主画布 + 辅助面板"场景:

┌──────────────────────┬──────────┐
│                      │          │
│        主操作区       │  辅助面板  │
│        2/3           │  1/3     │
│                      │          │
└──────────────────────┴──────────┘
// 启动 2:1 比例的 EasyGo,适用于创作工具
parallelVision.startEasyGo({
  leftPage: 'pages/CanvasEditor',   // 画布编辑区
  rightPage: 'pages/ToolPalette',    // 工具面板(调色板、笔刷)
  ratio: '2:1',
  linkType: 'tool',                 // 工具面板联动
  params: { canvasId: 'current' }
});

购物模式

购物模式是 EasyGo 针对电商场景专门优化的变体:

// 购物模式——左右联动,沉浸式比价
parallelVision.startEasyGo({
  leftPage: 'pages/ProductList',    // 商品列表(左)
  rightPage: 'pages/ProductDetail',  // 商品详情(右)
  mode: 'shopping',                  // 购物模式
  linkConfig: {
    // 选中商品时右侧自动跳转到详情
    autoSync: true,
    // 右侧滚动时左侧高亮对应商品
    highlightSync: true,
    // 可同时对比多个商品
    multiCompare: true
  }
});

购物模式的核心特性是双向联动:用户在左侧选择商品时右侧自动更新详情;用户在右侧浏览详情时左侧自动高亮对应商品。这种联动使得比价变得非常高效。

导航模式

导航模式专为地图导航场景设计:

// 导航模式——地图总览 + 路线详情
parallelVision.startEasyGo({
  leftPage: 'pages/MapOverview',    // 地图总览
  rightPage: 'pages/RouteDetail',   // 路线详情
  mode: 'navigation',
  linkConfig: {
    // 点击右侧路线时在地图上高亮
    highlightOnMap: true,
    // 地图缩放与右侧同步
    zoomSync: true
  }
});

二、EasyGo 与系统分屏的本质区别

很多开发者会问:EasyGo 分屏和系统级分屏(拖拽到屏幕边缘触发)有什么区别?答案是控制权的粒度不同

2.1 系统分屏的局限

系统分屏是操作系统层面的能力,用户可以将任意两个应用左右并排显示。但它的控制权在用户手中——应用开发者无法干预分屏中显示的内容、比例、联动行为。

系统分屏的优点:
├── 用户可以自由组合任意应用
├── 不需要应用做任何适配
└── 比例由用户拖拽调节

系统分屏的局限:
├── 应用无法控制默认比例
├── 应用无法预置左右页面内容
├── 不支持页面间联动(如列表选中→详情更新)
└── 不能自定义交互模式

2.2 EasyGo 的开发者控制力

EasyGo 则提供了应用开发者主导的分屏控制能力

控制维度 系统分屏 EasyGo
启动方 用户 应用代码或用户
默认比例 用户拖拽决定 开发者预设(1:2/2:1)
左右页面内容 两个独立应用 同一应用内的两个页面
页面间联动 不支持 支持(通过 linkConfig)
交互模式 通用 可定制(购物/导航等)
参数传递 不支持 通过 params 传递
状态共享 不支持 通过 AppStorage 共享

2.3 选择指南

场景 推荐方案 原因
同一应用内两个页面的协同 EasyGo 支持页面间联动和数据共享
两个不同应用的并排使用 系统分屏 跨应用场景唯一选择
电商比价 EasyGo 购物模式 内置双向联动,体验最优
画布+工具面板 EasyGo 2:1 主操作区更大空间
多任务办公 系统分屏 需要不同应用协同

三、应用内分屏——API 26 的新能力

3.1 什么是应用内分屏?

如果说 EasyGo 是应用级的分屏框架(一个应用分在两个页面),那么应用内分屏(In-App Split Screen)就是页面级的分屏能力。它允许在同一个页面内部将屏幕分割为两个独立区域,每个区域运行独立的组件树。

3.2 核心 API

应用内分屏的核心 API 位于 @kit.ArkUI 中:

import { SplitScreen } from '@kit.ArkUI';

@Component
struct CreativeStudio {
  build() {
    SplitScreen({
      // 分割方向
      direction: 'horizontal',    // 'horizontal' | 'vertical'
      // 默认分割比例(百分比)
      defaultRatio: 0.6,          // 左侧/上方占 60%
      // 最小比例
      minRatio: 0.3,
      // 最大比例
      maxRatio: 0.7,
      // 是否显示分割线
      divider: true,
      // 第一位子组件
      primary: () => {
        this.CanvasArea()
      },
      // 第二位子组件
      secondary: () => {
        this.PanelArea()
      }
    })
    .width('100%')
    .height('100%')
  }
}

3.3 应用内分屏的特性

特性 说明
方向控制 支持水平分割(左右)和垂直分割(上下)
比例调节 用户可拖拽分割线调整比例
比例限制 通过 minRatio/maxRatio 防止过度压缩某一侧
分割线定制 自定义分割线的颜色、宽度、样式
独立组件树 两侧组件拥有独立的生命周期和状态

3.4 与 EasyGo 的对比

维度 EasyGo 应用内分屏
层级 应用级(两个 Page) 页面级(一个 Page 内)
路由 两个独立路由栈 共享同一路由栈
状态共享 通过 AppStorage / 事件总线 通过 @State / @Link
适用场景 列表+详情、购物比价 画布+工具面板、编辑器内分栏
配置方式 声明式配置 + 代码启动 ArkUI 组件声明

四、配置式接入——声明式配置 EasyGo

EasyGo 最强大的特性之一是其配置式接入方式。应用可以通过 JSON 声明或代码声明两种方式定义 EasyGo 行为。

4.1 JSON 声明式配置

module.json5 或独立配置文件中声明 EasyGo 行为:

{
  "easyGo": {
    "enabled": true,
    "defaultMode": "1:2",
    "modes": [
      {
        "name": "shopping",
        "ratio": "1:2",
        "left": "pages/ProductList",
        "right": "pages/ProductDetail",
        "linkType": "detail"
      },
      {
        "name": "canvas",
        "ratio": "2:1",
        "left": "pages/CanvasEditor",
        "right": "pages/ToolPalette",
        "linkType": "tool"
      },
      {
        "name": "compare",
        "ratio": "1:1",
        "left": "pages/ArtworkViewer",
        "right": "pages/ArtworkViewer",
        "linkType": "compare",
        "compareMode": true
      }
    ],
    "supportedOrientations": ["landscape", "portrait"],
    "minScreenWidth": 600     // 仅在宽度 ≥ 600vp 时启用
  }
}

这种配置方式的优势在于:

  1. 声明式:将 EasyGo 行为从代码中剥离,便于维护和调整
  2. 多模式支持:可以在配置中定义多种分屏模式,按需切换
  3. 条件启用:可以通过 minScreenWidth 等条件自动适配不同设备

4.2 代码声明式配置

除了 JSON 配置,也可以通过代码动态配置:

import { parallelVision, EasyGoConfig } from '@kit.KernelKit';

class AppEasyGoManager {
  private config: EasyGoConfig = {
    enabled: true,
    defaultMode: '1:2',
    modes: [
      {
        name: 'shopping',
        ratio: '1:2',
        left: 'pages/ProductList',
        right: 'pages/ProductDetail',
        linkType: 'detail'
      }
    ],
    minScreenWidth: BreakpointConfig.lg // 复用断点系统的 lg 阈值
  };

  // 在 Ability 的 onCreate 中初始化
  initialize(context: UIAbilityContext) {
    parallelVision.configure(this.config);
  }

  // 运行时切换模式
  switchMode(modeName: string) {
    parallelVision.switchMode(modeName);
  }

  // 动态注册新的分屏模式
  registerMode(mode: EasyGoMode) {
    parallelVision.registerMode(mode);
  }
}

五、响应式布局的整合

EasyGo 与第 5 章讨论的响应式布局(BreakpointSystem + BreakPointType)天然契合。

5.1 根据断点决定是否启用 EasyGo

并不是所有设备都需要 EasyGo——手机竖屏(sm)下屏幕宽度有限,分屏反而会降低可用性。通过断点系统,可以精确控制 EasyGo 的启用条件:

// 根据当前断点决定是否启用 EasyGo
class EasyGoAwareComponent {
  @StorageLink('currentBreakpoint') currentBreakpoint: string = 'sm';

  get shouldEnableEasyGo(): boolean {
    // 仅在 md 及以上断点启用 EasyGo
    return !['sm'].includes(this.currentBreakpoint);
  }

  openInEasyGoIfNeeded(listPage: string, detailPage: string, params?: Object) {
    if (this.shouldEnableEasyGo) {
      parallelVision.startEasyGo({
        leftPage: listPage,
        rightPage: detailPage,
        ratio: '1:2',
        params: params || {}
      });
    } else {
      // sm 断点下退化为普通页面跳转
      this.getUIContext().getRouter().pushUrl({
        url: detailPage,
        params: params
      });
    }
  }
}

5.2 分屏比例随断点调节

不同断点下,最优的分屏比例是不同的:

// 断点感知的分屏比例
const EASYGO_RATIO = new BreakPointType<string>({
  sm: '1:1',     // 小屏不使用 EasyGo,备用值
  md: '2:1',     // 中屏:主区域更大
  lg: '1:2',     // 大屏:详情区域更大
  xl: '1:2'      // 超大屏:详情区域更大,充分利用宽屏
});

// 分屏内容区域的布局本身也应是响应式的
function startResponsiveEasyGo(breakpoint: string) {
  const ratio = EASYGO_RATIO.getValue(breakpoint);

  parallelVision.startEasyGo({
    // 根据断点选择不同的内容页面
    leftPage: breakpoint === 'md' ? 'pages/CompactList' : 'pages/FullList',
    rightPage: 'pages/ItemDetail',
    ratio: ratio,
    params: { breakpoint }
  });
}

5.3 应用内分屏的响应式适配

应用内分屏同样需要与响应式布局整合。当设备为小屏时,分屏可能无法正常使用,此时需要降级为单栏布局:

@Component
struct AdaptiveCreativeStudio {
  @StorageLink('currentBreakpoint') currentBreakpoint: string = 'sm';

  build() {
    Column() {
      if (this.currentBreakpoint === 'sm') {
        // 小屏:单栏,通过 Tab 切换画布和工具
        this.SingleColumnLayout()
      } else {
        // 中屏及以上:分屏显示
        SplitScreen({
          direction: 'horizontal',
          defaultRatio: 0.65,
          minRatio: 0.4,
          maxRatio: 0.8,
          primary: () => this.CanvasArea(),
          secondary: () => this.ToolPaletteArea()
        })
      }
    }
    .width('100%')
    .height('100%')
  }
}

六、典型用例:购物比价与辅助窗口

6.1 购物比价模式

购物比价是 EasyGo 最具代表性的场景之一。用户可以在一个应用中同时浏览商品列表和商品详情,无需反复切换页面。

交互流程:

用户在商品列表中浏览
    │
    ▼
点击某商品 → 右侧自动打开详情
    │
    ▼
用户在右侧浏览详情 →
左侧自动高亮当前商品
    │
    ▼
用户点击"对比" →
左右并排显示两个商品详情

项目中的代码实现思路:

// 比价场景的 EasyGo 启动逻辑
function startPriceComparison(context: Context) {
  parallelVision.startEasyGo({
    leftPage: 'pages/PriceListPage',
    rightPage: 'pages/ProductDetailPage',
    mode: 'shopping',
    ratio: '1:2',
    linkConfig: {
      autoSync: true,           // 选中自动同步右侧详情
      highlightSync: true,      // 滚动时同步高亮
      multiCompare: true,       // 支持多商品对比
      compareLimit: 4           // 最多同时对比 4 个商品
    }
  });
}

6.2 辅助窗口模式

辅助窗口模式是 EasyGo 的另一种重要应用形式——主应用在正常使用,辅助窗口提供额外的信息或工具支持。

┌──────────────────────┬────────────────┐
│                      │                │
│      主内容区          │   辅助窗口      │
│    (全屏正常使用)     │   (参考信息)   │
│                      │                │
│                      │                │
└──────────────────────┴────────────────┘

辅助窗口的典型场景包括:

场景 主窗口 辅助窗口
写作 编辑器 参考笔记/资料
编程 代码编辑器 文档/API 参考
设计 设计稿 色板/素材库
绘画 画布 调色板/笔刷/参考图

七、在"画伴梦工厂"中应用——创作模式

7.1 创作模式的痛点

在"画伴梦工厂"的当前设计中,用户创作时需要在画布、调色板、笔刷选择器、参考图之间频繁切换。典型的交互路径是:

画布上绘画 → 关闭画布 → 打开调色板 → 调整颜色 → 返回画布
→ 画几笔 → 打开笔刷选择器 → 调整笔刷大小 → 返回画布
→ 画几笔 → 打开参考图 → 查看参考 → 返回画布

这种"打开-关闭-返回"的模态切换模式打断了创作流,尤其在大屏设备上,屏幕空间本应允许这些工具同时可见。

7.2 方案一:EasyGo 画布+工具侧栏

利用 EasyGo 的 2:1 模式,将画布和工具面板并排显示:

// 启动创作模式的 EasyGo
function startCreativeEasyGo(canvasId: string) {
  parallelVision.startEasyGo({
    leftPage: 'pages/CanvasEditor',     // 左侧画布占 2/3
    rightPage: 'pages/CreativeToolPanel', // 右侧工具面板占 1/3
    ratio: '2:1',
    mode: 'creation',                    // 自定义创作模式
    linkConfig: {
      // 画布上选中元素时,右侧自动显示该元素的属性
      autoSync: true,
      // 工具面板中调整参数时,画布实时预览
      realtimePreview: true
    },
    params: {
      canvasId: canvasId,
      fromEasyGo: true                   // 标记,便于页面做适配
    }
  });
}

右侧工具面板的设计:

// CreativeToolPanel.ets
@Entry
@Component
struct CreativeToolPanel {
  @State private selectedTool: string = 'brush';
  @State private brushSize: number = 5;
  @State private color: string = '#000000';
  private canvasId: string = '';

  aboutToAppear() {
    const params = this.getUIContext().getRouter().getParams() as Record<string, Object>;
    this.canvasId = params?.['canvasId'] as string || '';

    // 监听来自画布的事件
    this.getUIContext().getEventHub().on('elementSelected', (elementId: string) => {
      // 当画布上选中元素时,自动加载其属性
      this.loadElementProperties(elementId);
    });
  }

  // 调整笔刷大小 → 通知画布实时更新
  onBrushSizeChange(newSize: number) {
    this.brushSize = newSize;
    AppStorage.set('brushSize', newSize);      // 通过 AppStorage 共享给画布
    AppStorage.set('needsBrushUpdate', true);   // 触发画布更新
  }

  build() {
    Column() {
      // 工具选择器
      Row() {
        this.ToolButton('brush', '画笔')
        this.ToolButton('eraser', '橡皮')
        this.ToolButton('fill', '填充')
        this.ToolButton('picker', '取色')
      }
      .padding(12)

      // 笔刷大小调节
      Text('笔刷大小')
      Slider({ value: this.brushSize, min: 1, max: 50 })
        .onChange((v) => this.onBrushSizeChange(v))

      // 调色板
      Text('颜色选择')
      ColorPicker({ selectedColor: this.color })
        .onChange((c) => {
          this.color = c;
          AppStorage.set('currentColor', c);
        })

      // 参考图区域
      Text('参考图')
      Image(this.referenceImage)
        .width('100%')
        .height(120)
        .objectFit(ImageFit.Contain)
    }
    .width('100%')
    .height('100%')
    .backgroundColor('#F5F5F5')
  }
}

7.3 方案二:应用内分屏的画布+参考图

另一种场景是用户在创作时需要参考另外一张图(比如参考实物照片来绘画)。使用应用内分屏可以实现画布和参考图的并排显示:

@Component
struct CanvasWithReference {
  @State private splitRatio: number = 0.55;

  build() {
    SplitScreen({
      direction: 'horizontal',
      defaultRatio: this.splitRatio,
      minRatio: 0.4,
      maxRatio: 0.7,
      primary: () => {
        // 画布区域
        Canvas(this.canvasContext)
          .width('100%')
          .height('100%')
          .onTouch((event) => {
            // 涂鸦逻辑
          })
      },
      secondary: () => {
        // 参考图区域
        Column() {
          Image($r('app.media.reference_photo'))
            .width('100%')
            .objectFit(ImageFit.Contain)
          Text('双指缩放参考图')
            .fontSize(12)
            .opacity(0.5)
        }
        .padding(8)
        .alignItems(HorizontalAlign.Center)
      }
    })
    .width('100%')
    .height('100%')
  }
}

7.4 方案三:画布+画廊对比(前后版本对比)

创作过程中,用户常常需要对比当前版本和之前保存的版本:

// 通过 EasyGo 对比两个版本
function compareVersions(versionA: string, versionB: string) {
  parallelVision.startEasyGo({
    leftPage: 'pages/ArtworkViewer',      // 左侧显示版本 A
    rightPage: 'pages/ArtworkViewer',     // 右侧显示版本 B
    ratio: '1:1',                         // 1:1 等分屏幕
    mode: 'compare',                      // 对比模式
    params: {
      leftImageId: versionA,
      rightImageId: versionB,
      compareMode: true                   // 开启对比模式
    }
  });
}

// ArtworkViewer.ets 中根据参数决定加载哪张图
aboutToAppear() {
  const params = this.getUIContext().getRouter().getParams() as Record<string, Object>;
  this.imageId = params?.['leftImageId'] || params?.['rightImageId'] || '';
  this.isCompareMode = params?.['compareMode'] === true;

  if (this.isCompareMode) {
    // 对比模式下隐藏交互工具栏,专注于显示
    this.showToolbar = false;
  }
}

7.5 三种方案的选型

方案 分屏方式 适用场景 推荐度
EasyGo 2:1 画布+工具 应用级分屏 日常创作,画布和工具并排 ⭐⭐⭐⭐⭐
应用内分屏 画布+参考图 页面级分屏 需要参考图辅助创作的场景 ⭐⭐⭐⭐
EasyGo 1:1 版本对比 应用级分屏 作品修改前后的版本对比 ⭐⭐⭐⭐

实际项目中,这三种方案可以组合使用。例如,默认使用 EasyGo 2:1 模式启动创作(画布+工具),当用户需要参考图时,在工具面板中点击"参考图"按钮,将工具面板切换为参考图显示模式。


八、与多设备形态适配的对比

8.1 两种能力的定位差异

维度 多设备形态适配(第 5.7 篇) EasyGo / 应用内分屏
目标 让 UI 在不同屏幕上看起来正确 让用户在同一个屏幕上做更多事
手段 断点切换、响应式取值、栅格布局 分屏框架、页面联动、比例控制
触发条件 屏幕宽度变化自动触发 用户主动操作或应用逻辑触发
交互复杂度 隐式适配,用户无感知 显式分屏,用户有感知
状态管理 @StorageLink 自动同步 AppStorage / 事件总线通信

8.2 两种能力的协同使用

多设备形态适配解决了"布局在不同尺寸上是否好看"的问题,而 EasyGo 解决了"大屏上用户如何充分利用空间"的问题。两者是递进关系:

第 5.7 篇 → 第 7.13 篇
┌──────────────────────────────────────┐
│  多设备形态适配(基础能力)              │
│  ├── 断点系统:sm/md/lg/xl            │
│  ├── 响应式布局:Tab 位置、栅格列数     │
│  └── 自适应布局:百分比、flexShrink     │
│                                        │
│  + EasyGo / 应用内分屏(高级能力)       │
│  ├── EasyGo:应用级分屏框架             │
│  ├── 应用内分屏:页面级分屏             │
│  └── 配置式接入:声明式 EasyGo 配置     │
└──────────────────────────────────────┘

具体到代码层面:

// 综合示例:根据断点决定是否使用 EasyGo 以及分屏比例
@Component
struct SmartCreativeExperience {
  @StorageLink('currentBreakpoint') currentBreakpoint: string = 'sm';

  private getEasyGoConfig(): EasyGoConfig | null {
    const configMap = new BreakPointType<EasyGoConfig | null>({
      sm: null,             // 手机竖屏:不分屏,使用全屏画布
      md: {                 // 小平板:画布+精简工具栏
        leftPage: 'pages/CanvasEditor',
        rightPage: 'pages/CompactToolPanel',
        ratio: '2:1'
      },
      lg: {                 // 大平板:画布+完整工具栏
        leftPage: 'pages/CanvasEditor',
        rightPage: 'pages/CreativeToolPanel',
        ratio: '2:1'
      },
      xl: {                 // 2in1:画布+完整工具栏+参考图区
        leftPage: 'pages/CanvasEditor',
        rightPage: 'pages/ExtendedToolPanel',
        ratio: '3:2'
      }
    });
    return configMap.getValue(this.currentBreakpoint);
  }
}

九、最佳实践

9.1 渐进增强原则

不要在所有设备上不加区分地启用 EasyGo。推荐的实施策略是:

基础体验:手机竖屏(sm)
├── 全屏单栏布局
├── 通过 Tab 或弹出面板切换工具
└── 无分屏能力

增强体验:中大屏(md/lg)
├── EasyGo 2:1 创作模式
├── 画布占 2/3,工具面板占 1/3
└── 侧边栏始终可见

极致体验:超大屏(xl)
├── EasyGo 多模式切换
├── 创作模式 / 对比模式 / 预览模式
└── 可拖拽调节分屏比例

9.2 状态同步策略

EasyGo 左右两侧页面通过 AppStorage 实现状态同步:

// 左侧页面(画布)——更新工具状态
AppStorage.set('brushSize', newSize);
AppStorage.set('currentColor', newColor);
AppStorage.set('selectedTool', 'eraser');

// 右侧页面(工具面板)——监听工具状态
@StorageLink('brushSize') brushSize: number = 5;
@StorageLink('currentColor') currentColor: string = '#000000';
@StorageLink('selectedTool') selectedTool: string = 'brush';

9.3 生命周期管理

EasyGo 中的左右页面拥有独立的生命周期,需要注意:

  • 两侧独立初始化:每个页面在 aboutToAppear 中只加载自身需要的数据
  • 不要重复请求:如果两侧都需要同一份数据(如用户信息),通过 AppStorage 共享而非各自请求
  • 退出时清理:当 EasyGo 关闭时,两侧页面都会触发 aboutToDisappear

9.4 降级方案

当设备不支持 EasyGo 或用户不允许分屏时,需要有合理的降级方案:

async function startWithFallback(listPage: string, detailPage: string, params?: Object) {
  try {
    // 先检测设备是否支持 EasyGo
    const isSupported = await parallelVision.isSupported();
    if (isSupported) {
      await parallelVision.startEasyGo({
        leftPage: listPage,
        rightPage: detailPage,
        ratio: '1:2'
      });
    } else {
      // 不支持则退化为普通跳转
      throw new Error('EasyGo not supported');
    }
  } catch (e) {
    // 降级:普通页面跳转
    getUIContext().getRouter().pushUrl({
      url: detailPage,
      params: params
    });
  }
}

9.5 性能考量

注意事项 说明
避免两栏同时加载大量数据 EasyGo 两侧页面会同时加载,注意控制初始数据量
懒加载 非可见区域使用 LazyForEach 延迟加载
状态去重 通过 AppStorage 共享状态,避免两侧独立请求同一数据
分屏切换动画 使用系统提供的过渡动画,避免自定义复杂动画导致掉帧
内存监控 分屏模式下同时渲染两个页面,注意监控内存使用

总结

平行视界 EasyGo 与应用内分屏是 HarmonyOS 7 在大屏多窗口交互领域的重要创新。它们不是简单的"把屏幕切成两半",而是一套完整的、由开发者主导的、配置驱动的分屏能力体系。

知识点 核心内容 关键要点
EasyGo 应用级分屏启动框架 1:2 / 2:1 / 购物模式 / 导航模式
应用内分屏 页面级 SplitScreen 组件 水平/垂直分割、比例可调
配置式接入 JSON / 代码声明式配置 多模式预置、条件启用
与系统分屏区别 开发者控制力 比例、内容、联动均可控
与响应式布局整合 断点感知的分屏策略 sm→单栏 / md+→分屏
项目应用 创作模式画布+工具面板 2:1 比例,AppStorage 状态同步
最佳实践 渐进增强 + 降级方案 检测支持能力,提供 fallback

对于"画伴梦工厂"这样的创作工具,EasyGo 的应用内分屏能力几乎是为其量身定做的——用户在画布上创作时,所有工具触手可及;查看参考图时,无需离开创作界面;对比多个版本时,左右并排一目了然。这些体验的升级,正是从"好用的应用"到"出色的创作平台"的关键跨越。


思考题:在"画伴梦工厂"中,如果用户在 EasyGo 分屏模式下创作(左侧画布、右侧工具),此时用户旋转设备从横屏变为竖屏,断点从 lg 变为 sm。思考如何实现"从分屏到单栏"的平滑过渡?应该在 BreakpointSystem 的回调中关闭 EasyGo 并切换为全屏画布,还是让用户在单栏模式下通过底部面板切换工具?结合第 5.7 篇的断点系统和本文的 EasyGo API,给出你的设计方案。

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐