欢迎光临
我们一直在努力

HarmonyOS7 富文本渲染:RichText + Web 渲染 HTML 内容的正确方式

文章目录

      • 前言
      • 富文本需求场景
      • RichText 组件
      • 支持的 HTML 标签
      • Web 渲染复杂 HTML
      • 两种方案对比
      • 图片点击处理
      • 写在最后

前言

A hand-drawn doodle illustration on pure white pap

后端扔过来一段 HTML,让我在 App 里展示。我一上来就用 Text 组件硬拼 Span,拼到第三个标签人就崩了——这得拼到猴年马月?

后来发现 HarmonyOS7 有专门的富文本渲染方案。今天聊聊两种主流方式:RichText 组件和 Web 组件,帮你根据场景选对路子。 富文本渲染是内容型 App 的刚需。新闻详情、公告说明、商品描述……后端返回的几乎都是 HTML。前端要做的事就一件:把 HTML 渲染成好看的 UI。

听起来简单,但坑不少:标签支持不全、图片点击没反应、样式跟原生不一致……选错方案,后面全是补丁。

富文本需求场景

不同场景对富文本的要求差异很大:

场景HTML 复杂度交互需求推荐方案
用户协议 / 隐私政策 简单(p/a/b 标签为主) 无 RichText
新闻详情 中等(图文混排) 图片点击放大 RichText

A hand-drawn doodle illustration on pure white pap

| 活动页 / 营销页 | 复杂(CSS 动画+JS 交互) | 高 | Web | | 第三方网页嵌入 | 不可控 | 全交互 | Web |

简单总结:内容为主用 RichText,交互为主用 Web。

RichText 组件

RichText 是 HarmonyOS7 专门为 HTML 内容渲染设计的组件,用法简单粗暴——直接把 HTML 字符串塞进去:

@Entry
@Component
struct RichTextDemo {
private htmlContent: string = `
<h2>HarmonyOS7 更新公告</h2>
<p>本次更新带来了<strong>全新的 ArkUI 组件</strong>,性能提升显著。</p>
<ul>
<li>新增 Flex 弹性布局组件</li>
<li>优化 List 滚动性能</li>
<li>修复已知 <em>50+</em> 问题</li>
</ul>
<p>详细内容请访问<a href="https://developer.huawei.com">开发者官网</a>。</p>
`

build() {
Scroll() {
Column() {
RichText(this.htmlContent)
.width('100%')
.padding(16)
.onReady(() => {
console.info('RichText 渲染完成')
})
}
}
.width('100%')
.height('100%')
}
}

A hand-drawn doodle illustration on pure white pap

关键代码讲解:

  • RichText(this.htmlContent) —— 直接传入 HTML 字符串,组件自动解析渲染
  • .onReady() —— 渲染完成的回调,可以在这里做后续处理(比如图片加载后的高度调整)
  • RichText 只支持通用属性中的 width、height、size、layoutWeight,不能设 fontSize、fontColor 这些文本属性——因为样式由 HTML 标签控制

RichText 的样式完全由 HTML 内联决定,想改字号得在 HTML 里写 <span style="font-size:18px">。

支持的 HTML 标签

RichText 不是啥 HTML 标签都支持,以下是常用标签的支持情况:

标签说明示例
<h1>~<h6> 标题 <h2>标题</h2>
<p> 段落 <p>内容</p>
<a> 超链接 <a href="url">链接</a>
<strong> / <b> 加粗 <b>加粗</b>
<em> / <i> 斜体 <i>斜体</i>
<u> 下划线 <u>下划线</u>
<s> 删除线 <s>删除</s>
<ul> / <ol> 列表 <ul><li>项</li></ul>
<img> 图片 <img src="url">
<table> 表格 <table><tr><td>…</td></tr></table>
<div> / <span> 容器 <div style="…">…</div>
<br> 换行 <br>
<hr> 分割线 <hr>

不支持的标签会被直接忽略,不会报错也不会显示。所以用之前先确认你的 HTML 里有没有奇奇怪怪的标签。

Web 渲染复杂 HTML

当 HTML 包含复杂 CSS、JavaScript 或者 RichText 不支持的标签时,就得用 Web 组件了:

import webview from '@ohos.web.webview'

@Entry
@Component
struct WebRichTextDemo {
private webController: webview.WebviewController = new webview.WebviewController()
private htmlContent: string = `
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style>
body { margin: 0; padding: 16px; font-family: sans-serif; color: #333; }
h2 { color: #007DFF; }
.highlight { background: linear-gradient(120deg, #f6d365 0%, #fda085 100%);
padding: 4px 8px; border-radius: 4px; }
.card { background: #f8f8f8; border-radius: 12px; padding: 16px; margin: 12px 0; }
img { max-width: 100%; border-radius: 8px; }
</style>
</head>
<body>
<h2>限时活动</h2>
<div class="card">
<p>活动期间,<span class="highlight">全场商品8折</span>!</p>
<img src="https://example.com/banner.jpg" onclick="onImageClick(this.src)">
</div>
<script>
function onImageClick(src) {
window.postMessage(JSON.stringify({type:'imageClick', src: src}));
}
</script>
</body>
</html>
`

build() {
Column() {
Web({ src: '', controller: this.webController })
.width('100%')
.layoutWeight(1)
.javaScriptAccess(true)
.domStorageAccess(true)
.onPageEnd(() => {
this.webController.loadData(
this.htmlContent,
'text/html',
'UTF-8'
)
})
.onMessage((event) => {
let data = JSON.parse(event.data as string)
if (data.type === 'imageClick') {
console.info(`图片被点击: ${data.src}`)
}
})
}
.width('100%')
.height('100%')
}
}

关键代码讲解:

  • javaScriptAccess(true) —— 必须开启,不然 <script> 里的代码不执行
  • domStorageAccess(true) —— 开启 DOM 存储,某些 HTML 依赖 localStorage
  • loadData() —— 加载 HTML 字符串,三个参数分别是内容、MIME 类型、编码
  • onMessage() —— 接收 HTML 里 window.postMessage() 发送的消息,这是 Web 和原生通信的桥梁
  • onPageEnd() —— 页面加载完成时触发,在这里注入 HTML 内容比较稳妥

Web 组件嵌套在 Scroll 里时,别忘了加 .nestedScroll() 处理滚动冲突。

两种方案对比

维度RichTextWeb
渲染性能 高(原生渲染) 低(WebView 引擎)
HTML 支持度 有限(基础标签) 完整(含 CSS/JS)
交互能力 仅链接点击 完整 JS 交互
内存占用 低 高
样式控制 受限(只支持4个通用属性) 灵活(CSS 全支持)
与原生通信 onReady 回调 postMessage 双向通信
加载速度 快 慢(需初始化引擎)

图片点击处理

RichText 里的图片点击是个常见需求,可惜 RichText 本身没有直接提供图片点击回调。变通方案:

方案一:用 onReady + 正则替换

build() {
RichText(this.processHtml(this.htmlContent))
.width('100%')
.padding(16)
}

processHtml(html: string): string {
return html.replace(
/<img\\s+src="([^"]*)"/g,
'<img src="$1" onclick="window.open(\\'$1\\')"'
)
}

方案二:直接用 Web 组件

如果图片点击交互比较复杂(比如要弹出预览、左右滑动),老老实实用 Web + postMessage,别折腾了。

写在最后

选方案的核心判断:HTML 有没有 CSS 动画或 JS 交互?

  • 没有 → RichText,轻快省
  • 有 → Web,别犹豫

别想着用 RichText 硬撑复杂 HTML,后期补丁比重写还痛苦。也别啥都用 Web,一个简单的用户协议页加个 WebView,内存占用直接翻倍。

选对工具,事半功倍。

赞(0)
未经允许不得转载:171主机测评 » HarmonyOS7 富文本渲染:RichText + Web 渲染 HTML 内容的正确方式
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址