HarmonyOS应用开发实战:萌宠日记 - 富文本编辑器扩展思路
前言
富文本编辑器是日记类应用的进阶功能,它允许用户在文字中插入加粗、斜体、图片、链接等丰富格式,让日记内容更加生动多样。萌宠日记当前版本使用纯文本编辑器(TextInput + TextArea),但为未来的富文本编辑能力预留了扩展空间。
本文属于前瞻性设计文章,从萌宠日记现有架构出发,探讨富文本编辑器的技术选型、架构设计、功能规划,以及实现路线图。
一、富文本编辑器的功能需求
1.1 功能清单
| 功能模块 | 功能项 | 优先级 | 说明 |
|---|---|---|---|
| 文字样式 | 加粗、斜体、下划线 | P0 | 基础文字格式 |
| 文字样式 | 字体大小、颜色 | P1 | 文字个性化 |
| 段落样式 | 标题级别(H1-H3) | P0 | 文章结构 |
| 段落样式 | 有序/无序列表 | P0 | 列表展示 |
| 多媒体 | 图片插入 | P0 | 图文混排 |
| 多媒体 | 视频插入 | P2 | 视频记录 |
| 链接 | 文本链接 | P1 | 引用外部资源 |
| 引用 | 引用块 | P1 | 引用内容 |
| 对齐 | 左/中/右/两端对齐 | P2 | 段落排版 |
1.2 核心功能对比
| 功能 | 当前纯文本 | 富文本 | 差异 |
|---|---|---|---|
| 文字格式 | 纯文本 | 支持加粗、斜体、颜色 | 表现力提升 |
| 图片 | 独立附件区 | 图文混排 | 布局更灵活 |
| 排版 | 固定样式 | 可自定义 | 个性化更强 |
| 数据存储 | 纯文本字符串 | HTML / Markdown | 存储更复杂 |
二、技术选型方案
2.1 方案对比
| 方案 | 技术路线 | 优点 | 缺点 |
|---|---|---|---|
| RichText 组件 | HarmonyOS 原生 | 原生支持,性能好 | 功能有限 |
| WebView + 富文本库 | 加载 HTML 编辑器 | 功能强大,生态丰富 | 性能开销大 |
| 自定义富文本组件 | 基于 Text 组件扩展 | 定制化强 | 开发成本高 |
| Markdown 编辑器 | 编辑 Markdown 文本 | 存储简单,可扩展 | 需学习成本 |
2.2 推荐方案:Markdown 编辑器
// Markdown 编辑器架构 // 1. 编辑时:使用 TextArea 编辑 Markdown 源码 // 2. 预览时:将 Markdown 渲染为富文本 // 3. 存储时:存储 Markdown 字符串 // Markdown 语法示例 const markdownContent = ` # 愉快的周末 今天带**豆豆**去公园玩了飞盘,它跑得特别开心! ## 活动记录 - 散步:30分钟 - 飞盘:15分钟 - 社交:认识了一只新朋友 > 豆豆今天特别兴奋! `三、RichText 组件
3.1 组件基础
HarmonyOS 提供了RichText 组件用于渲染富文本内容:
// RichText 组件基本用法 RichText('<h1>愉快的周末</h1><p>今天带<b>豆豆</b>去公园</p>') .width('100%') .onStart(() => { console.log('RichText render start') }) .onComplete(() => { console.log('RichText render complete') })3.2 RichText 支持的 HTML 标签
| 标签 | 说明 | 示例 |
|---|---|---|
<h1>-<h6> | 标题 | <h1>标题</h1> |
<p> | 段落 | <p>正文</p> |
<b> | 加粗 | <b>加粗文字</b> |
<i> | 斜体 | <i>斜体文字</i> |
<u> | 下划线 | <u>下划线</u> |
<img> | 图片 | <img src="url" /> |
<a> | 链接 | <a href="url">链接</a> |
<ul>/<li> | 无序列表 | <ul><li>项</li></ul> |
<ol>/<li> | 有序列表 | <ol><li>项</li></ol> |
四、富文本编辑架构
4.1 编辑器架构
┌─────────────────────────────────────────┐ │ RichTextEditor │ │ ┌───────────────────────────────────┐ │ │ │ 工具栏(Toolbar) │ │ │ │ [B] [I] [U] [H1] [IMG] [LINK] │ │ │ └───────────────────────────────────┘ │ │ ┌───────────────────────────────────┐ │ │ │ 编辑区(EditorArea) │ │ │ │ 支持富文本格式的编辑区域 │ │ │ └───────────────────────────────────┘ │ │ ┌───────────────────────────────────┐ │ │ │ 预览区(Preview) │ │ │ │ RichText 渲染富文本效果 │ │ │ └───────────────────────────────────┘ │ └─────────────────────────────────────────┘4.2 组件设计
// 富文本编辑器组件结构 @Component export struct RichTextEditor { @State content: string = '' // 富文本内容(HTML/Markdown) @State isPreview: boolean = false // 是否预览模式 build() { Column() { // 工具栏 this.Toolbar() if (this.isPreview) { // 预览模式 RichText(this.content) .width('100%') } else { // 编辑模式 TextArea({ placeholder: '开始记录...' }) .width('100%') .height(300) .onChange((value: string) => { this.content = value }) } } } @Builder Toolbar() { Row({ space: 8 }) { this.ToolButton('B', () => this.insertBold()) // 加粗 this.ToolButton('I', () => this.insertItalic()) // 斜体 this.ToolButton('U', () => this.insertUnderline()) // 下划线 this.ToolButton('H1', () => this.insertHeading(1)) // 标题 this.ToolButton('IMG', () => this.insertImage()) // 图片 this.ToolButton('🔗', () => this.insertLink()) // 链接 } .width('100%') .padding(8) .backgroundColor('#F5F5F5') .borderRadius(8) } }五、工具栏设计
5.1 工具按钮
@Builder ToolButton(label: string, onClick: () => void) { Button(label) .fontSize(14) .fontColor('#333333') .backgroundColor('#FFFFFF') .borderRadius(6) .width(40) .height(32) .onClick(onClick) }5.2 格式化操作
// 插入加粗标记(Markdown 模式) insertBold(): void { this.content += '**加粗文字**' } // 插入斜体标记 insertItalic(): void { this.content += '*斜体文字*' } // 插入标题 insertHeading(level: number): void { const prefix = '#'.repeat(level) this.content += `\n${prefix} 标题\n` } // 插入图片 insertImage(): void { // 打开图片选择器 this.selectPhoto().then((uri: string) => { this.content += `\n\n` }) } // 插入链接 insertLink(): void { this.content += `[链接文字](https://example.com)` }六、Markdown 渲染
6.1 Markdown 转 HTML
// 简单的 Markdown 到 HTML 转换 function markdownToHtml(md: string): string { let html = md // 标题 .replace(/^### (.+)$/gm, '<h3>$1</h3>') .replace(/^## (.+)$/gm, '<h2>$1</h2>') .replace(/^# (.+)$/gm, '<h1>$1</h1>') // 加粗 .replace(/\*\*(.+?)\*\*/g, '<b>$1</b>') // 斜体 .replace(/\*(.+?)\*/g, '<i>$1</i>') // 图片 .replace(/!\[(.+?)\]\((.+?)\)/g, '<img src="$2" alt="$1" />') // 链接 /\[(.+?)\]\((.+?)\)/g, '<a href="$2">$1</a>') // 换行 .replace(/\n/g, '<br/>') return `<div>${html}</div>` }七、富文本数据存储
7.1 存储方案对比
| 存储格式 | 存储内容 | 优势 | 劣势 |
|---|---|---|---|
| Markdown | 纯文本 | 可读性强、版本控制友好 | 需渲染 |
| HTML | 标签字符串 | 直接渲染 | 可读性差 |
| JSON | 结构化数据 | 精确控制、可扩展 | 复杂 |
7.2 推荐:Markdown 存储
// 使用 Markdown 格式存储富文本内容 interface DiaryData { // ... 其他字段 contentType: 'plain' | 'markdown' // 内容类型 content: string // Markdown 或纯文本 } // 保存时 const diaryData: DiaryData = { contentType: 'markdown', content: `# 愉快的周末\n\n今天带**豆豆**去公园...` } // 渲染时 if (diaryData.contentType === 'markdown') { // 转换为 HTML 并使用 RichText 渲染 const html = markdownToHtml(diaryData.content) RichText(html) } else { // 纯文本渲染 Text(diaryData.content) }八、渐进式实现路线
8.1 实现阶段
| 阶段 | 功能 | 目标 | 复杂度 |
|---|---|---|---|
| Phase 1 | 纯文本 + 照片附件 | 当前版本 | 低 |
| Phase 2 | Markdown 编辑 + 预览 | 基础富文本 | 中 |
| Phase 3 | 工具栏 + 格式化操作 | 完整编辑体验 | 高 |
| Phase 4 | 图文混排 + 多媒体 | 高级富文本 | 高 |
8.2 Phase 2 实现
// Phase 2:Markdown 编辑 + 预览模式 @State isPreview: boolean = false build() { Column() { // 切换按钮 Row() { Text('编辑') .fontColor(this.isPreview ? '#999999' : '#F5A623') .onClick(() => { this.isPreview = false }) Text('预览') .fontColor(this.isPreview ? '#F5A623' : '#999999') .onClick(() => { this.isPreview = true }) } if (this.isPreview) { // 预览模式 RichText(markdownToHtml(this.content)) .width('100%') } else { // 编辑模式 TextArea({ placeholder: '使用 Markdown 格式记录...' }) .width('100%') .height(300) .onChange((value: string) => { this.content = value }) } } }九、性能考量
9.1 性能优化
| 优化策略 | 说明 |
|---|---|
| 懒加载渲染 | 仅在预览模式时渲染 RichText |
| Markdown 缓存 | 缓存转换结果,避免重复转换 |
| 图片懒加载 | 图片在可见时加载 |
| 编辑区保持 | 切换编辑/预览时保持编辑状态 |
十、最佳实践
10.1 富文本编辑器实现原则
有序列表 — 富文本编辑器实现的 5 个原则:
- 渐进式实现:从纯文本 → Markdown → 富文本,逐步迭代
- 编辑预览分离:编辑模式保持简洁,预览模式展示效果
- 存储格式选择:推荐 Markdown,可读性强,扩展性好
- 工具栏轻量:保留最常用的格式化功能,避免过度设计
- 兼容当前数据:确保富文本内容与纯文本内容兼容
10.2 萌宠日记编辑器演进路线
| 版本 | 编辑器类型 | 说明 |
|---|---|---|
| V1.0 | 纯文本 TextArea | 当前版本 |
| V1.1 | Markdown 编辑 + 预览 | 短期目标 |
| V1.2 | 工具栏 + 格式化 | 中期目标 |
| V2.0 | 图文混排 RichText | 长期目标 |
总结
本文从萌宠日记现有的纯文本编辑器出发,前瞻性地探讨了富文本编辑器的扩展方案:
- 功能需求:10 项富文本功能,按优先级划分
- 技术选型:Markdown 编辑 + RichText 渲染方案
- RichText 组件:支持 HTML 标签的富文本渲染
- 编辑器架构:工具栏 + 编辑区 + 预览区
- Markdown 转换:Markdown 到 HTML 的转换函数
- 数据存储:Markdown 格式存储,兼容性强
- 渐进式实现:4 个阶段逐步演进
- 性能优化:懒加载、缓存、编辑状态保持
至此,模块五:日记编写的 9 篇文章全部完成。下一篇我们将进入模块六:健康记录,首篇解析健康记录分类导航设计。
如果这篇文章对你有帮助,欢迎点赞👍、收藏⭐、关注🔔,你的支持是我持续创作的动力!
相关资源:
- RichText 组件:https://developer.huawei.com/consumer/cn/doc/harmonyos-references/ts-basic-components-richtext
- TextArea 组件:https://developer.huawei.com/consumer/cn/doc/harmonyos-references/ts-basic-components-textarea
- Markdown 语法:https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/markdown
- WebView 组件:https://developer.huawei.com/consumer/cn/doc/harmonyos-references/ts-basic-components-web
- 图片加载:https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/image-optimization
- 数据持久化:https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/app-data-persistence
- 性能优化:https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/performance-optimization
- 组件化设计:https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/component-based-design