鸿蒙5.0开辟进阶:UI框架-富文本(RichEditor)

立山  论坛元老 | 2024-12-17 03:53:48 | 显示全部楼层 | 阅读模式
打印 上一主题 下一主题

主题 1008|帖子 1008|积分 3024

往期鸿蒙全套实战文章必看:



  • 鸿蒙开辟焦点知识点,看这篇文章就够了
  • 最新版!鸿蒙HarmonyOS Next应用开辟实战学习路线
  • 鸿蒙HarmonyOS NEXT开辟技术最全学习路线指南
  • 鸿蒙应用开辟实战项目,看这一篇文章就够了(部分项目附源码)

富文本(RichEditor)

RichEditor是支持图文混排和文本交互式编辑的组件,通常用于响应用户的对于图文混淆内容的输入操作,例如可以输入图片的评论区。
创建RichEditor组件

RichEditor通过调用接口来创建,可以创建以下两种范例:
创建不使用属性字符串构建的RichEditor组件

  1. RichEditor(value: RichEditorOptions)
复制代码
其中RichEditorOptions是富文本组件初始化选项。
  1. controller: RichEditorController = new RichEditorController();
  2. options: RichEditorOptions = { controller: this.controller };
  3. RichEditor(this.options)
  4. .onReady(() => {
  5. this.controller.addTextSpan('创建不使用属性字符串构建的RichEditor组件。', {
  6. style: {
  7. fontColor: Color.Black,
  8. fontSize: 15
  9. }
  10. })
  11. })
复制代码


创建使用属性字符串构建的RichEditor组件

  1. RichEditor(options: RichEditorStyledStringOptions)
复制代码
其中RichEditorStyledStringOptions是富文本组件初始化选项。
  1. mutableStyledString: MutableStyledString = new MutableStyledString("创建使用属性字符串构建的RichEditor组件。",
  2. [{
  3. start: 0,
  4. length: 5,
  5. styledKey: StyledStringKey.FONT,
  6. styledValue: this.fontStyle
  7. }]);
  8. controller: RichEditorStyledStringController = new RichEditorStyledStringController();
  9. options: RichEditorStyledStringOptions = {controller: this.controller};
  10. RichEditor(this.options)
  11. .onReady(() => {
  12. this.controller.setStyledString(this.mutableStyledString);
  13. })
复制代码


设置属性

设置自定义选择菜单

通过bindSelectionMenu设置自定义选择菜单。
其中spanType是菜单的范例,默认值为文字范例;content是菜单的内容;responseType是菜单的响应范例,默认范例为长按;options是菜单的选项,可设置自定义选择菜单弹出或关闭时的回调。
自定义菜单超长时,建议内部嵌套Scroll组件使用,制止键盘被遮挡。
  1. RichEditor(this.options)
  2. .onReady(() => {
  3. this.controller.addTextSpan('组件设置了自定义菜单,长按可触发。', {
  4. style: {
  5. fontColor: Color.Black,
  6. fontSize: 18
  7. }
  8. })
  9. })
  10. .bindSelectionMenu(RichEditorSpanType.TEXT, this.SystemMenu, ResponseType.LongPress, {
  11. onDisappear: () => {
  12. this.sliderShow = false
  13. }
  14. })
  15. .width(300)
  16. .height(300)
  17. @Builder
  18. SystemMenu() {
  19. Column() {
  20. Menu() {
  21. if (this.controller) {
  22. MenuItemGroup() {
  23. MenuItem({
  24. startIcon: this.theme.cutIcon,
  25. content: "剪切",
  26. labelInfo: "Ctrl+X",
  27. })
  28. MenuItem({
  29. startIcon: this.theme.copyIcon,
  30. content: "复制",
  31. labelInfo: "Ctrl+C"
  32. })
  33. MenuItem({
  34. startIcon: this.theme.pasteIcon,
  35. content: "粘贴",
  36. labelInfo: "Ctrl+V"
  37. })
  38. }
  39. }
  40. }
  41. .radius(this.theme.containerBorderRadius)
  42. .clip(true)
  43. .backgroundColor(Color.White)
  44. .width(this.theme.defaultMenuWidth)
  45. }
  46. .width(this.theme.defaultMenuWidth)
  47. }
复制代码


设置输入框光标、手柄颜色

通过caretColor设置输入框光标、手柄颜色。
  1. RichEditor(this.options)
  2. .onReady(() => {
  3. this.controller.addTextSpan('组件设置了光标手柄颜色。', {
  4. style: {
  5. fontColor: Color.Black,
  6. fontSize: 15
  7. }
  8. })
  9. })
  10. .caretColor(Color.Orange)
  11. .width(300)
  12. .height(300)
复制代码


设置无输入时的提示文本

通过placeholder设置无输入时的提示文本。
其中value为无输入时的提示文本;style为添加提示文本的字体样式,style缺省时默认跟随主题。
  1. RichEditor(this.options)
  2. .placeholder("此处为提示文本...", {
  3. fontColor: Color.Gray,
  4. font: {
  5. size: 15,
  6. weight: FontWeight.Normal,
  7. family: "HarmonyOS Sans",
  8. style: FontStyle.Normal
  9. }
  10. })
  11. .width(300)
  12. .height(300)
复制代码


添加事故

添加组件初始化完成后可触发的回调

通过onReady来添加组件初始化完成后可触发的回调。
其中callback是订阅富文本组件初始化完成的回调。
  1. RichEditor(this.options)
  2. .onReady(() => {
  3. this.controller.addTextSpan('onReady回调内容是组件内预置文本。', {
  4. style: {
  5. fontColor: Color.Black,
  6. fontSize: 15
  7. }
  8. })
  9. })
复制代码


添加组件内容被选中时可触发的回调

通过onSelect来添加组件内容被选中时可触发的回调。
在callback中,RichEditorSelection为选中的所有内容信息。
触发该回调有两种方式:可通过鼠标左键按下选择,松开左键后触发回调,也可通过手指选择,松开手指触发回调。
  1. RichEditor(this.options)
  2.     .onReady(() => {
  3.         this.controller.addTextSpan('选中此处文本,触发onselect回调。', {
  4.             style: {
  5.                 fontColor: Color.Black,
  6.                 fontSize: 15
  7.             }
  8.         })
  9.     })
  10.     .onSelect((value: RichEditorSelection) => {
  11.         this.controller1.addTextSpan(JSON.stringify(value), {
  12.             style: {
  13.                 fontColor: Color.Gray,
  14.                 fontSize: 10
  15.             }
  16.         })
  17.     })
  18.     .width(300)
  19.     .height(50)
  20. Text('查看回调内容:').fontSize(10).fontColor(Color.Gray).width(300)
  21. RichEditor(this.options1)
  22.     .width(300)
  23.     .height(70)
复制代码


添加图文变革前和图文变革后可触发的回调

通过onWillChange添加图文变革前可触发的回调。通过onDidChange添加图文变革后可触发的回调。
onWillChange的callback中:RichEditorChangeValue为图文变革信息;boolean为true时,表示当前图文允许被更改。boolean为false时,表示当前图文不允许被更改。
onDidChange的callback中:OnDidChangeCallback为图文变革前后的内容范围。
使用RichEditorStyledStringOptions构建的RichEditor组件不支持这两种回调。
  1. RichEditor(this.options)
  2. .onReady(() => {
  3. this.controller.addTextSpan('组件内图文变化前,触发回调。\n图文变化后,触发回调。', {
  4. style: {
  5. fontColor: Color.Black,
  6. fontSize: 15
  7. }
  8. })
  9. })
  10. .onWillChange((value: RichEditorChangeValue) => {
  11. this.controller1.addTextSpan('组件内图文变化前,触发回调:\n' + JSON.stringify(value), {
  12. style: {
  13. fontColor: Color.Gray,
  14. fontSize: 10
  15. }
  16. })
  17. return true;
  18. })
  19. .onDidChange((rangeBefore: TextRange, rangeAfter: TextRange) => {
  20. this.controller1.addTextSpan('\n图文变化后,触发回调:\nrangeBefore:' + JSON.stringify(rangeBefore) + '\nrangeAfter:' + JSON.stringify(rangeBefore), {
  21. style: {
  22. fontColor: Color.Gray,
  23. fontSize: 10
  24. }
  25. })
  26. return true;
  27. })
  28. .width(300)
  29. .height(50)
  30. Text('查看回调内容:').fontSize(10).fontColor(Color.Gray).width(300)
  31. RichEditor(this.options1)
  32. .width(300)
  33. .height(70)
复制代码


添加输入法输入内容前和完成输入后可触发的回调

通过aboutToIMEInput添加输入法输入内容前可触发的回调。通过onIMEInputComplete添加输入法完成输入后可触发的回调。
aboutToIMEInput的callback中:RichEditorInsertValue为输入法将要输入内容信息;boolean为true时,组件执行添加内容操作。boolean为false时,组件不执行添加内容操作。
onIMEInputComplete的callback中:RichEditorTextSpanResult为输入法完成输入后的文本Span信息。
使用RichEditorStyledStringOptions构建的RichEditor组件不支持这两种回调。
  1. RichEditor(this.options)
  2. .onReady(() => {
  3. this.controller.addTextSpan('输入法输入内容前,触发回调。\n输入法完成输入后,触发回调。' , {
  4. style: {
  5. fontColor: Color.Black,
  6. fontSize: 15
  7. }
  8. })
  9. })
  10. .aboutToIMEInput((value: RichEditorInsertValue) => {
  11. this.controller1.addTextSpan('输入法输入内容前,触发回调:\n'+JSON.stringify(value), {
  12. style: {
  13. fontColor: Color.Gray,
  14. fontSize: 10
  15. }
  16. })
  17. return true;
  18. })
  19. .onIMEInputComplete((value: RichEditorTextSpanResult) => {
  20. this.controller1.addTextSpan('输入法完成输入后,触发回调:\n'+ JSON.stringify(value), {
  21. style: {
  22. fontColor: Color.Gray,
  23. fontSize: 10
  24. }
  25. })
  26. return true;
  27. })
  28. .width(300)
  29. .height(50)
  30. Text('查看回调内容:').fontSize(10).fontColor(Color.Gray).width(300)
  31. RichEditor(this.options1)
  32. .width(300)
  33. .height(70)
复制代码


添加完成粘贴前可触发的回调

通过onPaste添加完成粘贴前可触发的回调。
其中callback用于定义用户粘贴事故。
由于体系的默认粘贴,只支持纯文本的粘贴。以是开辟者可以通过该方法,覆盖体系默认举动,实现图文的粘贴。
  1. RichEditor(this.options)
  2. .onReady(() => {
  3. this.controller.addTextSpan('对此处文本进行复制粘贴操作可触发对应回调。', {
  4. style: {
  5. fontColor: Color.Black,
  6. fontSize: 15
  7. }
  8. })
  9. })
  10. .onPaste(() => {
  11. this.controller1.addTextSpan('触发onPaste回调\n', {
  12. style: {
  13. fontColor: Color.Gray,
  14. fontSize: 10
  15. }
  16. })
  17. })
  18. .width(300)
  19. .height(70)
复制代码
添加完成剪切前可触发的回调

通过onCut添加完成粘贴前可触发的回调。
其中callback用于定义用户剪切事故。
由于体系的默认剪切举动,只支持纯文本的剪切。以是开辟者可以通过该方法,覆盖体系默认举动,实现图文的剪切。
  1. RichEditor(this.options)
  2. .onReady(() => {
  3. this.controller.addTextSpan('对此处文本进行复制粘贴操作可触发对应回调。', {
  4. style: {
  5. fontColor: Color.Black,
  6. fontSize: 15
  7. }
  8. })
  9. })
  10. .onCut(() => {
  11. this.controller1.addTextSpan('触发onCut回调\n', {
  12. style: {
  13. fontColor: Color.Gray,
  14. fontSize: 10
  15. }
  16. })
  17. })
  18. .width(300)
  19. .height(70)
复制代码
添加完成复制前可触发的回调

通过onCopy添加完成粘贴前可触发的回调。
其中callback用于定义用户复制事故。
由于体系的默认复制举动,只支持纯文本的复制。以是开辟者可以通过该方法,覆盖体系默认举动,实现图文的复制。
  1. RichEditor(this.options)
  2. .onReady(() => {
  3. this.controller.addTextSpan('对此处文本进行复制粘贴操作可触发对应回调。', {
  4. style: {
  5. fontColor: Color.Black,
  6. fontSize: 15
  7. }
  8. })
  9. })
  10. .onCopy(() => {
  11. this.controller1.addTextSpan('触发onCopy回调\n', {
  12. style: {
  13. fontColor: Color.Gray,
  14. fontSize: 10
  15. }
  16. })
  17. })
  18. .width(300)
  19. .height(70)
复制代码


设置用户预设的样式

通过setTypingStyle设置用户预设的样式。
其中value是预设样式。
  1. RichEditor(this.options)
  2. .onReady(() => {
  3. this.controller.addTextSpan('点击按钮,改变组件预设样式。', {
  4. style: {
  5. fontColor: Color.Black,
  6. fontSize: 15
  7. }
  8. })
  9. })
  10. .width(300)
  11. .height(60)
  12. Button('setTypingStyle', {
  13. buttonStyle: ButtonStyleMode.NORMAL
  14. })
  15. .height(30)
  16. .fontSize(13)
  17. .onClick(() => {
  18. this.controller.setTypingStyle({
  19. fontWeight: 'medium',
  20. fontColor: Color.Pink,
  21. fontSize: 15,
  22. fontStyle: FontStyle.Italic,
  23. decoration: {
  24. type: TextDecorationType.Underline,
  25. color: Color.Gray
  26. }
  27. })
  28. })
复制代码


设置组件内的内容选中时部分背板高亮

通过setSelection设置组件内的内容选中时部分背板高亮。
其中selectionStart为选中开始位置,selectionEnd选中结束位置。当selectionStart和selectionEnd均为-1时表示全选。
当组件内未获焦出现光标时,调用该接口不产生选中效果。
  1. RichEditor(this.options)
  2. .onReady(() => {
  3. this.controller.addTextSpan('点击按钮在此处选中0-2位置的文本。', {
  4. style: {
  5. fontColor: Color.Black,
  6. fontSize: 15
  7. }
  8. })
  9. })
  10. .width(300)
  11. .height(60)
  12. Button('setSelection(0,2)', {
  13. buttonStyle: ButtonStyleMode.NORMAL
  14. })
  15. .height(30)
  16. .fontSize(13)
  17. .onClick(() => {
  18. this.controller.setSelection(0, 2)
  19. })
复制代码


添加文本内容

除了直接在组件内输入内容,也可以通过addTextSpan添加文本内容。
其中value是文本内容;options是文本选项,用于添加文本的偏移位置和文本样式信息(RichEditorTextSpanOptions)。
如果组件光标闪烁,插入后光标位置更新为新插入文本的后面。
  1. RichEditor(this.options)
  2. .onReady(() => {
  3. this.controller.addTextSpan('点击按钮在此处添加text。', {
  4. style: {
  5. fontColor: Color.Black,
  6. fontSize: 15
  7. }
  8. })
  9. })
  10. .width(300)
  11. .height(100)
  12. Button('addTextSpan', {
  13. buttonStyle: ButtonStyleMode.NORMAL
  14. })
  15. .height(30)
  16. .fontSize(13)
  17. .onClick(() => {
  18. this.controller.addTextSpan('新添加一段文字。')
  19. })
复制代码


添加图片内容

通过addImageSpan添加图片内容。
其中value是图片内容;options是图片选项,用于添加图片的偏移位置和图片样式信息(RichEditorImageSpanOptions)。
添加图片内容,如果组件光标闪烁,插入后光标位置更新为新插入图片的后面。
  1. RichEditor(this.options)
  2. .onReady(() => {
  3. this.controller.addTextSpan('点击按钮在此处添加image。', {
  4. style: {
  5. fontColor: Color.Black,
  6. fontSize: 15
  7. }
  8. })
  9. })
  10. .width(300)
  11. .height(100)
  12. Button('addImageSpan', {
  13. buttonStyle: ButtonStyleMode.NORMAL
  14. })
  15. .height(30)
  16. .fontSize(13)
  17. .onClick(() => {
  18. this.controller.addImageSpan($r("app.media.startIcon"), {
  19. imageStyle: {
  20. size: ["57px", "57px"]
  21. }
  22. })
  23. })
复制代码


添加builder内容

通过addBuilderSpan添加builder内容。
其中value是builder内容;options是builder选项,可通过RichEditorBuilderSpanOptions设置此builder在RichEditor中的index(一个文字为一个单元)。
  1. @Builder
  2. TextBuilder() {
  3. Row() {
  4. Image($r('app.media.startIcon')).width(50).height(50).margin(16)
  5. Column() {
  6. Text("文本文档.txt").fontWeight(FontWeight.Bold).fontSize(16)
  7. Text("123.45KB").fontColor('#8a8a8a').fontSize(12)
  8. }.alignItems(HorizontalAlign.Start)
  9. }.backgroundColor('#f4f4f4')
  10. .borderRadius("20")
  11. .width(220)
  12. }
  13. Button('addBuilderSpan', {
  14. buttonStyle: ButtonStyleMode.NORMAL
  15. })
  16. .height(30)
  17. .fontSize(13)
  18. .onClick(() => {
  19. this.my_builder = () => {
  20. this.TextBuilder()
  21. }
  22. this.controller.addBuilderSpan(this.my_builder)
  23. })
复制代码


添加SymbolSpan内容

可通过addSymbolSpan添加SymbolSpan内容。
其中value是SymbolSpan组件内容;options是SymbolSpan组件选项,用于添加SymbolSpan组件的偏移位置和SymbolSpan组件样式信息( RichEditorSymbolSpanOptions )。
添加SymbolSpan内容,如果组件光标闪烁,插入后光标位置更新为新插入Symbol的后面。
SymbolSpan内容暂不支持手势、复制、拖拽处置处罚。
  1. RichEditor(this.options)
  2. .onReady(() => {
  3. this.controller.addTextSpan('点击按钮在此处添加symbol。', {
  4. style: {
  5. fontColor: Color.Black,
  6. fontSize: 15
  7. }
  8. })
  9. })
  10. .width(300)
  11. .height(100)
  12. Button('addSymbolSpan', {
  13. buttonStyle: ButtonStyleMode.NORMAL
  14. })
  15. .height(30)
  16. .fontSize(13)
  17. .onClick(() => {
  18. this.controller.addSymbolSpan($r("sys.symbol.basketball_fill"), {
  19. style: {
  20. fontSize: 30
  21. }
  22. })
  23. })
复制代码


获取组件内span信息

可通过getSpans获取组件内span信息。
其中value是必要获取span范围。返回值为Array<RichEditorTextSpanResult | RichEditorImageSpanResult>,是文本和图片Span信息。
  1. RichEditor(this.options)
  2. .onReady(() => {
  3. this.controller.addTextSpan('点击按钮获取此处span信息。', {
  4. style: {
  5. fontColor: Color.Black,
  6. fontSize: 15
  7. }
  8. })
  9. })
  10. .width(300)
  11. .height(50)
  12. Text('查看getSpans返回值:').fontSize(10).fontColor(Color.Gray).width(300)
  13. RichEditor(this.options1)
  14. .width(300)
  15. .height(50)
  16. Button('getSpans', {
  17. buttonStyle: ButtonStyleMode.NORMAL
  18. })
  19. .height(30)
  20. .fontSize(13)
  21. .onClick(() => {
  22. this.controller1.addTextSpan(JSON.stringify(this.controller.getSpans()), {
  23. style: {
  24. fontColor: Color.Gray,
  25. fontSize: 10
  26. }
  27. })
  28. })
复制代码


 
看完三件事❤️



  • 如果你以为这篇内容对你还蛮有帮助,我想邀请你帮我三个小忙:
  • 点赞,转发,有你们的 『点赞和评论』,才是我创造的动力。
  • 关注作者,不定期分享原创知识。
  • 同时可以期待后续文章ing

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

立山

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表