HarmonyOS ArkTS 沉浸式效果(Immersive Effects)全面指南

HarmonyOS ArkTS 沉浸式效果(Immersive Effects)全面指南

鸿蒙第四期开发者活动

沉浸式效果 的本质,是让应用的 UI 内容延伸到屏幕的最边缘 —— 包括系统状态栏和底部导航栏区域,让界面看起来更“大更通透”,提升用户视觉体验和沉浸感。
在许多 App 里,例如浏览器无标题栏模式、游戏启动页、图片展示页、内容优先型页面,都会用到沉浸式处理。developer.huawei.comHarmonyOS ArkTS 富文本编辑组件(RichEditor)详解

富文本编辑器是指支持图文混排、可交互式编辑的文本输入区域,它不仅能够像普通输入框那样输入字符,还能支持样式设置、插入图片/表情等高级操作,是编写富文本内容(例如长评论、文章发布、邮件正文、帖子编辑)时的重要组件。华为开发者


一、什么是 RichEditor?

RichEditor 是 HarmonyOS ArkTS 提供的一种专用富文本编辑组件,它:

  • 支持图文混排(文字 + 图片 + 风格样式)
  • 允许用户对输入内容进行交互式编辑
  • 提供事件监听和内容管理能力

它比 TextInput 更强:不仅仅是输入纯文本,更像是一个可视化的内容编辑区域,用于创建结构化/格式化内容。华为开发者


二、RichEditor 适合的典型场景

场景 说明
发布帖子/文章 用户输入带格式的内容(粗体、列表等)
多媒体评论 允许用户在评论里插入图片/表情
邮件/富文本消息 需要文本加样式、段落格式
内容编辑器 管理更丰富的排版和文本结构

TextInput(只能输入“纯文本”)对比,RichEditor 适合可视化富文本场景


三、核心要素组成

1. RichEditor 组件

这是主控的 UI 区域,你可以直接渲染在页面里:

RichEditor(this.options)

其中 this.options 是一个配置对象(官方文档称为 RichEditorOptions),用于提供控制器等信息来初始化组件。Atbigapp


2. RichEditorController

它是你操作富文本编辑器内容的“引擎”。常用于:

  • 插入文本或图像
  • 控制光标位置
  • 获取当前富文本内容
  • 动态修改内容样式
controller: RichEditorController = new RichEditorController();
options: RichEditorOptions = { controller: this.controller };

在创建 RichEditor 时,把它传给编辑器实例,后续通过它来操控编辑器。DEV Community


四、基础使用示例(一步步写起来)

下面是一个完整的“可运行版”结构示例,展示如何在 ArkTS 页面里渲染并使用 RichEditor:

@Component
struct RichEditorDemo {
  controller: RichEditorController = new RichEditorController();
  options = { controller: this.controller };

  build() {
    Column({ space: 12 }) {
      Text('富文本编辑器示例').fontSize(18).fontWeight(FontWeight.Bold);

      RichEditor(this.options)
        .width('100%')
        .height(280)
        .backgroundColor(0xFFFFFFFF)
        .onReady(() => {
          // 编辑器准备好后可以插入初始内容
          this.controller.addTextSpan('欢迎使用富文本编辑器!')
        })
        .onCopy((evt) => {
          // 用户复制事件
          promptAction.showToast({ message: '内容已复制', duration: 1200 })
        });
    }
    .padding(12)
  }
}

功能细节:

  • .onReady(...):编辑器初始化完毕回调
  • .onCopy(...):用户执行文字复制时触发回调
  • controller.addTextSpan(...):在打开编辑器后动态追加内容(例如引导文本)DEV Community

五、常见 API 与用法

下面是开发过程中你最有可能用到的一些能力:


1. 初始化编辑器内容

当页面加载时,你可以在 onReady 回调里通过 controller 设置初始文本、默认样式等:

.onReady(() => {
  this.controller.addTextSpan('初始内容');
})

这比把字符串直接塞进属性更灵活,因为它是在编辑器渲染后执行。DEV Community


2. 事件监听

富文本编辑器通常有不少事件可以监听,例如:

  • onReady:编辑器初始化完成
  • onCopy:用户复制选中内容
  • onTextChange(如果支持):文本内容变化时触发

上面例子里我们监听了 onCopy 并弹出提示,这在“用户选中文字做动作”场景特有。DEV Community


3. 插入图像 / 图片

RichEditor 一般支持插入富文本图像。
在一些社区文章和示例里可以看到这类能力(插入图片、图标等元素的位置及样式需要通过 Controller 提供的接口操作)。CSDN

示例思路(伪代码):

this.controller.insertImage('https://example.com/img.jpg', { width: 200, height: 120 });

上面代码在光标位置插入图片(具体 API 名称/参数请从官方 API 参考查阅对应字段)。


4. 加样式(粗体/斜体)

通过 Controller 或 Option/Dom 操作,可以为特定段落应用样式,如粗体、斜体、链接等。这类样式操作通常结合 Span 风格控制(某些社区资源提到 Span 在富文本里同样能串联使用)。掘金


六、实战常见技巧与构建思路

1) 插入初始提示语

在富文本评论/编辑器页面里,加入“请输入内容…”的启动提示通常比不写更友好:

.onReady(() => this.controller.addTextSpan('在这里输入你的内容...'));

2) 结合按钮触发样式

在 UI 上放几个按钮,比如“粗体 / 插入图片 / 加链接”,通过 Controller 操作实现:

Button('插入图片').onClick(() => {
  this.controller.insertImage(url, { width: 100, height: 100 });
});

这种写法类似富文本编辑器工具栏,很适合内容创作场景。


3) 获取当前内容并提交

在用户点击“提交”按钮时获取编辑器内容,然后存回服务器:

const content = this.controller.getContent(); // 得到富文本数据
sendToServer(content);

不同版本的 API 名称可能略有差异,但思路是“Controller 拿当前实际内容”。

七、注意事项和坑(实战积累)


1) 性能问题

富文本编辑器在处理大量图文混排内容时可能较重(尤其是图片 + 嵌套内容)。因此:

  • 在长列表中反复创建 RichEditor 会有性能损耗
  • 尽量避免在短时间内高频创建/销毁组件

如果遇到性能瓶颈,可以考虑在背景线程做内容处理([turn0search13])。


2) 内容高度自适应

RichEditor 在某些场景下不会自动根据内容高度变化,要通过容器的布局约束适配高度,否则可能出现滚动条/裁剪。


3) 版本差异性

官方文档的 API 可能会随版本微调,你在使用 controlleroptions 时,要参考对应 SDK 版本的 API 说明(部分回调、方法名、参数结构等可能会变化)。


🏁 八、总结(像人写的结论)

  • RichEditor 是 ArkTS 提供的原生富文本编辑组件,适用于用户创作和图文混排场景。华为开发者
  • 它由 RichEditor + RichEditorController + RichEditorOptions 共同协作实现,可动态插入内容、监听事件等。DEV Community
  • 典型用法包括初始化内容、事件监听、插入图像、样式控制等。DEV Community
  • 实际开发中还要注意性能、布局自适应和版本 API 的细节。

一、为什么需要沉浸式效果

从用户体验角度看:

  1. 最大化屏幕可视空间
    默认情况下,系统会为状态栏和导航栏预留“安全区”空间,应用内容不覆盖。沉浸式让你把内容延伸到这些区域,整体布局更充分、更自由。developer.huawei.com
  2. 提升界面一体感
    当界面顶部或底部是纯色区域或大图时,如果内容被状态栏/导航栏截断,就会感觉“断层”。沉浸式消除断层,视觉更统一。developer.huawei.com
  3. 适配不同屏幕和设备
    包括全面屏、刘海屏、底部手势导航的设备,沉浸式结合安全区处理,更加灵活。developer.huawei.com

小结:沉浸式更像是一套全屏布局策略,让 UI 可以从“被动避让”变成“主动布局”。视觉上更大更整洁。developer.huawei.com


二、沉浸式的两种核心实现方式

沉浸式并不是单纯“关掉状态栏”,而是让应用内容延伸到系统 UI 区域,与系统栏协同布局:

方式一:设置全屏布局(Window 全屏)

通过系统窗口管理 API,把整个窗口设置为全屏模式,让内容不再回避状态栏和导航栏。

核心调用:

windowClass.setWindowLayoutFullScreen(true)
  .then(() => {
    console.info('已开启全屏沉浸式布局');
  })
  .catch(err => {
    console.error('设置失败', err);
  });
  • true:开启沉浸式布局,应用 UI 会覆盖状态栏/导航栏区域
  • false:恢复默认 UIKit 安全区避让布局

这个方法作用于整个窗口,适合“整页沉浸式”场景。developer.huawei.com


方式二:组件级延展安全区域(expandSafeArea)

在某些页面或某个组件需要沉浸式显示时,我们可以使用组件属性(如某些容器组件的 expandSafeArea)来扩大其安全区域,让它扩展到状态栏/导航栏附近。

Image("bg.png")
  .width("100%")
  .height("100%")
  .expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.TOP]);
  • SafeAreaType.SYSTEM:状态栏避让区域
  • SafeAreaEdge.TOP:指定扩展到顶部安全区
    (不同设备和平台可能有不同类型和 edge 配置)

这种方式适合局部沉浸式,例如顶部背景图覆盖状态栏但正文内容不遮挡。developer.huawei.com


三、沉浸式开发流程

下面是真正集成沉浸式效果的典型步骤(适合 ArkTS + DevEco Studio):


1. 在 Ability 里开启全屏布局

通常在 onWindowStageCreate() 或 Ability 生命周期的合适时机,开启沉浸式:

import window from '@ohos.window';

export default class MainAbility extends UIAbility {
  onWindowStageCreate(windowStage) {
    const mainWin = windowStage.getMainWindowSync();
    // 开启沉浸式
    mainWin.setWindowLayoutFullScreen(true);
  }
}

如果不希望所有页面都沉浸式,可以在页面级别再关闭。developer.huawei.com


2. 获取系统避让区域高度(状态栏/导航栏)

当你的布局需要保留一些空间(比如顶部标题栏不被内容遮住,底部 Tab 不被底部遮住),需要动态读取系统安全区高度:

const win = await window.getLastWindow(this.context);
let avoidArea = win.getWindowAvoidArea(window.AvoidAreaType.TYPE_SYSTEM);
this.statusBarHeight = px2vp(avoidArea.topRect.height);
// 底部导航栏避让
avoidArea = win.getWindowAvoidArea(window.AvoidAreaType.TYPE_NAVIGATION_INDICATOR);
this.navBarHeight = px2vp(avoidArea.bottomRect.height);
  • TYPE_SYSTEM:状态栏避让区
  • TYPE_NAVIGATION_INDICATOR:导航栏避让区
  • px2vp():把 px 转换为 VP 单位

拿到这些高度后,可以在页面布局中用来设置 Padding 或占位。developer.huawei.com


3. 页面布局适配与占位示例

在需要留出空间的页面,把获取到的状态栏/导航栏高度作为 padding/占位:

@Column>
  <Blank height={this.statusBarHeight} visibility={Visibility.Hidden} />
  <Header title="沉浸式标题" />
  ...
  <Blank height={this.navBarHeight} visibility={Visibility.Hidden} />
</Column>

这样做是为了解决“内容延伸到状态栏下,但可视内容不会被遮住”的问题。developer.huawei.com


四、常见沉浸式页面场景

沉浸式并不是所有页面都适合,典型的适用场景包括:

启动页 / 封面页 — 通常顶部大图全屏延伸
图片/视频浏览界面 — 不想看到系统栏的分隔
阅读/内容沉浸页 — 内容核心区域占据全屏
地图/游戏等沉浸式体验页面 — UI 透明处理更自然

这些场景都需要最大化可视区域,而沉浸式能让设计师“内容不被系统 UI 肢解”。developer.huawei.com


五、配合 UI 组件做更好的沉浸式体验

1) 渐变标题栏

即使是沉浸式,你也往往不会把所有内容和状态栏混在一起,往顶部加入一个渐变或背景,可以让状态栏图标在任何背景上都清晰可见。

技巧:

  • Stack 放置背景图 + 半透明遮罩
  • 顶部留出 statusBarHeight 的高度做真正的可点击区

2) 底部导航安全区

当页面下方有 BottomBar/TabBar 时,不要直接放到底部 0,而是保留 navBarHeight 的空间,再将 TabBar 放在它之上,这样既沉浸式又不遮挡交互元素。


六、常见误区与注意事项

误区 1:沉浸式就是“隐藏状态栏”

不是隐藏,而是内容覆盖系统栏区域。你仍然可能需要保留可点击区域以免 UI 元素挤到状态栏/导航栏下。developer.huawei.com


误区 2:沉浸式页面所有区域都随意扩展

沉浸式布局应配合安全区高度储存和占位调整,否则 UI 元素会被状态栏遮挡或与导航手势冲突。developer.huawei.com


误区 3:只在 UI 组件里写 padding 就够了

不是每种情况都靠组件 padding 解决,因为不同设备安全区高度可能不同。所以先读取 AvoidArea 再布局才是稳妥做法。developer.huawei.com


七、总结

沉浸式效果是打造现代 UI 的重要手段,在 ArkTS/ArkUI 框架下,它的核心是在:

  1. 开启全屏布局
  2. 读取系统避让区域高度
  3. 在布局中合理处理状态栏/导航栏占位

把状态栏/导航栏区域当成可控空间而不是遮挡区,每个 UI 元素来得更自由、更统一、更专注于内容。developer.huawei.com

posted @ 2025-12-22 08:54  想喝冰咖啡  阅读(0)  评论(0)    收藏  举报