鸿蒙5.0实战案例:基于RichEditor的批评编辑

打印 上一主题 下一主题

主题 994|帖子 994|积分 2982

往期推文全新看点(文中附带全新鸿蒙5.0全栈学习笔录)

✏️ 鸿蒙(HarmonyOS)北向开辟知识点记载~

✏️ 鸿蒙(OpenHarmony)南向开辟保姆级知识点汇总~

✏️ 鸿蒙应用开辟与鸿蒙体系开辟哪个更有前景?

✏️ 嵌入式开辟适不得当做鸿蒙南向开辟?看完这篇你就相识了~

✏️ 对于大前端开辟来说,转鸿蒙开辟究竟是福还是祸?

✏️ 鸿蒙岗位需求突增!移动端、PC端、IoT到底该怎么选?

✏️ 记载一场鸿蒙开辟岗位口试经历~

✏️ 持续更新中……


场景描述

RichEditor是支持图文混排和文本交互式编辑的组件,在我们利用的APP中是很常见的,好比批评区编辑内容发布、对话框或者谈天室。下面列举一些遇到的场景需求:


  • 场景一:基于文字图片以及@信息的好友批评
  • 场景二:右下角的剩余字数
  • 场景三:批评中携带所@的用户的附属信息
  • 场景四:文本选择区域发生变化或编辑状态下光标位置发生变化回调
  • 场景五:自由切换体系键盘和自定义键盘。
方案描述

场景一:基于文字图片以及@信息的好友批评

效果图

方案
1、通过addTextSpan来添加文字,2、通过addImageSpan来添加图片3、通过addBuilderSpan来实现一段内容光标不可插入的效果4、addTextSpan等支持gesture等手势操纵,好比onClick点击和onLongPress长按事件
核心代码
1、由于RichEditor是支持图文混排的,以是RichEditor里面的内容也就是由Text和Image构成的,分别通过addTextSpan和addImageSpan添加,而且还可以设置字体和图片样式,如下代码1:
  1. @Entry
  2. @Component
  3. struct getSpans {
  4. editorController = new RichEditorController()
  5. build() {
  6. Column() {
  7. RichEditor({ controller: this.editorController })
  8. .width('100%')
  9. .backgroundColor(Color.Yellow)
  10. .onReady(() => {
  11. this.editorController.addImageSpan($r("app.media.icon"),
  12. {
  13. imageStyle:
  14. {
  15. size: ["100px", "100px"]
  16. }
  17. })
  18. this.editorController.addTextSpan('男生女生向前冲',
  19. {
  20. style:
  21. {
  22. fontColor: Color.Blue,
  23. fontSize: 30
  24. }
  25. })
  26. })
  27. Button('getSpans-图片').onClick((event: ClickEvent) => {
  28. let getSpans = this.editorController.getSpans({ start: 0 })
  29. console.log('getSpans0' + JSON.stringify(getSpans[0]))
  30. // 必须进行强转才能获取文字信息或者图片信息
  31. let span0 = getSpans[0] as RichEditorTextSpanResult
  32. console.log('图片相关的信息: ' + JSON.stringify(span0))
  33. })
  34. Button('getSpans-文字').onClick((event: ClickEvent) => {
  35. let getSpans = this.editorController.getSpans({ start: 0 })
  36. console.log('getSpans1' + JSON.stringify(getSpans[1]))
  37. let span1 = getSpans[1] as RichEditorImageSpanResult
  38. console.log('文字相关的信息: ' + JSON.stringify(span1))
  39. })
  40. }
  41. }
  42. }
复制代码
2、在常见的批评区艾特好友时,会将“@华为官方客服”视作一个整体,光标无法插入其中,且第一次按删除键时整领会高亮选中,第二次再按删除键才会删除。**必要注意的是,如果利用的全局@Builder,则必要配合bind(this)利用。**后续也可以通过事件制止“即RichEditor控件ClickEvent/TouchEvent支持preventDefault”。
  1. @Entry
  2. @Component
  3. struct BuilderSpan {
  4. editorController = new RichEditorController()
  5. @Builder
  6. At(str: string) {
  7. Stack() {
  8. Text('@' + str).fontColor(Color.Blue)
  9. }
  10. }
  11. build() {
  12. Column() {
  13. RichEditor({ controller: this.editorController })
  14. .width('100%')
  15. .height(50)
  16. .backgroundColor(Color.Yellow)
  17. .onReady(() => {
  18. this.editorController.addBuilderSpan(() => {
  19. this.At('华为官方客服')
  20. })
  21. this.editorController.addTextSpan('!!!')
  22. })
  23. }
  24. }
  25. }
复制代码
3、发微博的时候可以输入心情、超链接、文字等一起的内容
代码3:
  1. @Component
  2. struct Index {
  3. @State message: string = '#超话社区#';
  4. controller: RichEditorController = new RichEditorController();
  5. @State show: boolean = false;
  6. build() {
  7. Column() {
  8. RichEditor({controller: this.controller})
  9. .height(56)
  10. .width("90%")
  11. .borderStyle(BorderStyle.Solid)
  12. .borderColor(Color.Black)
  13. .borderWidth(1)
  14. .onReady(() => {
  15. })
  16. Button('输入表情').onClick((event: ClickEvent) => {
  17. this.controller.addImageSpan($r('app.media.app_icon'), {
  18. imageStyle: {
  19. size: ["80px", "80px"]
  20. }
  21. })
  22. })
  23. Button('超链接').onClick((event: ClickEvent) => {
  24. this.controller.addTextSpan(this.message, {
  25. offset: this.controller.getCaretOffset(),
  26. style:
  27. {
  28. fontColor: Color.Orange,
  29. fontSize: 16
  30. },
  31. gesture:
  32. {
  33. onClick: () => {
  34. console.log('要跳转链接了哦')
  35. },
  36. onLongPress: () => {
  37. console.log('我被长按了')
  38. }
  39. }
  40. })
  41. this.controller.setCaretOffset(this.controller.getCaretOffset() + this.message.length)
  42. })
  43. }
  44. .width('100%')
  45. }
  46. }
复制代码
场景二:右下角的剩余字数

效果图

方案
利用overlay浮层,显示“0/20”字数提示符在组件的右下角。再通过aboutToIMEInput回调(输入法输入内容前),获取插入的文本偏移位置,对输入内容举行限制。
核心代码
  1. import promptAction from '@ohos.promptAction';
  2. @Entry
  3. @Component
  4. struct MaxDemo {
  5. @State message: string = '蜡笔小新';
  6. controller: RichEditorController = new RichEditorController();
  7. @State getContentLength: number = 0;
  8. @State BOnSt:promptAction.ShowToastOptions = {'message': '已超出内容最大限制.'}
  9. build() {
  10. Column() {
  11. RichEditor({ controller: this.controller })
  12. .height(100)
  13. .borderWidth(1)
  14. .borderColor(Color.Red)
  15. .width("100%")
  16. .overlay(this.getContentLength + "/20", {
  17. align: Alignment.BottomEnd
  18. })
  19. .aboutToIMEInput((value: RichEditorInsertValue) => {
  20. console.log("insertOffset:" + JSON.stringify(value.insertValue)) // 插入的文本偏移位置。
  21. if (this.getContentLength < 20) {
  22. this.getContentLength = this.getContentLength + value.insertValue.length
  23. console.log('实时的内容长度:' + this.getContentLength)
  24. return true
  25. }
  26. promptAction.showToast(this.BOnSt)
  27. return false
  28. })
  29. .aboutToDelete((value: RichEditorDeleteValue) => {
  30. console.log('删除:' + JSON.stringify(value))
  31. this.getContentLength = this.getContentLength - value.length
  32. return true
  33. })
  34. }
  35. .width('100%')
  36. }
  37. }
复制代码
场景三:批评中携带所@的用户的附属信息

效果图


方案
利用HashMap的set向HashMap中添加或更新一组数据,利用get方法获取指定key所对应的value。
核心代码
  1. @Entry
  2. @Component
  3. struct SameNameDemo {
  4. controller: RichEditorController = new RichEditorController();
  5. @Builder
  6. At(str: string) {
  7. Stack() {
  8. Text('@' + str).fontColor(Color.Blue)
  9. }
  10. .onClick(() => {
  11. // 添加不同的身份信息
  12. const hashMap: HashMap<string, number> = new HashMap();
  13. hashMap.set("friend1", 123);
  14. let result = hashMap.get("friend1");
  15. console.log('result: ' + result)
  16. })
  17. }
  18. build() {
  19. Column() {
  20. RichEditor({ controller: this.controller })
  21. .height(100)
  22. .borderWidth(1)
  23. .borderColor(Color.Red)
  24. .width("100%")
  25. Button('好友1').onClick((event: ClickEvent) => {
  26. this.controller.addBuilderSpan(() => {
  27. this.At('华为官方客服')
  28. })
  29. })
  30. Button('好友2').onClick((event: ClickEvent) => {
  31. this.controller.addBuilderSpan(() => {
  32. this.At('华为官方客服')
  33. })
  34. })
  35. }
  36. .width('100%')
  37. }
  38. }
复制代码
场景四:文本选择区域发生变化或编辑状态下光标位置发生变化回调

效果图

方案
利用RichEditor组件在API 12支持的新接口 onSelectionChange,在文本选择区域发生变化或编辑状态下光标位置发生变化时触发该回调。光标位置发生变化回调时,选择区域的起始位置等于终止位置(即start = end)。
核心代码
  1. @Entry
  2. @Component
  3. struct Index {
  4. @State message: string = '蜡笔小新';
  5. controller: RichEditorController = new RichEditorController();
  6. @State show: boolean = false;
  7. build() {
  8. Column() {
  9. RichEditor({controller: this.controller})
  10. .defaultFocus(true)
  11. .padding(0)
  12. .height(56)
  13. .width("90%")
  14. .borderStyle(BorderStyle.Solid)
  15. .borderColor(Color.Black)
  16. .borderWidth(1)
  17. .padding({left: 10})
  18. .onReady(() => {
  19. this.controller.addTextSpan(this.message, {
  20. offset: this.controller.getCaretOffset(),
  21. style:
  22. {
  23. fontColor: Color.Orange,
  24. fontSize: 16
  25. }
  26. })
  27. this.controller.setCaretOffset(this.controller.getCaretOffset() + this.message.length)
  28. })
  29. .onSelectionChange((value:RichEditorRange) => {
  30. console.log('光标位置改变了')
  31. console.log('start: ' + value.start)
  32. console.log('end: ' + value.end)
  33. })
  34. }
  35. .width('100%')
  36. }
  37. }
复制代码
场景五:自由切换体系键盘和自定义键盘

效果图

方案
利用RichEditor的属性customKeyboard控制切换体系键盘还是自定义键盘,添加心情利用addImageSpan,删除内容利用deleteSpans,并通过获取光标地点位置举行删除。
核心代码
  1. @Entry
  2. @Component
  3. struct Index {
  4. @State message: string = 'Hello World';
  5. controller = new RichEditorController()
  6. @State showKeyboard:boolean = false;
  7. private listData: (string | number | Resource)[] = [
  8. $r('app.media.img'), $r('app.media.img_1'), $r('app.media.img_2'), $r('app.media.img_3'), $r('app.media.img_4'), $r('app.media.img_5'), $r('app.media.img_6'),
  9. $r('app.media.img'), $r('app.media.img_1'), $r('app.media.img_2'), $r('app.media.img_3'), $r('app.media.img_4'), $r('app.media.img_5'), $r('app.media.img_6'),
  10. $r('app.media.img'), $r('app.media.img_1'), $r('app.media.img_2'), $r('app.media.img_3'), $r('app.media.img_4'), $r('app.media.img_5'), $r('app.media.img_6'),
  11. $r('app.media.img'), $r('app.media.img_1'), $r('app.media.img_2'), $r('app.media.img_3'), $r('app.media.img_4'), $r('app.media.img_5'), $r('app.media.img_6'),
  12. $r('app.media.img'), $r('app.media.img_1'), $r('app.media.img_2'), $r('app.media.img_3'), $r('app.media.img_4'), $r('app.media.img_5'), $r('app.media.img_6'),
  13. ];
  14. // 自定义键盘组件
  15. @Builder CustomKeyboardBuilder() {
  16. Column() {
  17. Text('自定义表情键盘')
  18. .fontSize(25)
  19. .fontWeight(900)
  20. Grid() {
  21. ForEach(this.listData, (item: string | number | Resource) => {
  22. GridItem() {
  23. if (typeof item !== 'number' && typeof item !== 'string') {
  24. Image(item)
  25. .width(30).onClick(() => {
  26. this.controller.addImageSpan(item, { imageStyle: { size: ['110px', '110px'] } })
  27. })
  28. }
  29. }
  30. })
  31. }.columnsGap(10).rowsGap(10).padding(5)
  32. Row() {
  33. Image($r('app.media.img_7'))
  34. .width(30)
  35. .onClick(() => {
  36. this.controller.deleteSpans({start: this.controller.getCaretOffset() - 1, end: this.controller.getCaretOffset()})
  37. })
  38. }
  39. .width('100%')
  40. .justifyContent(FlexAlign.End)
  41. .margin({ bottom: 40 })
  42. }
  43. .borderColor(Color.Gray)
  44. .borderWidth(5)
  45. }
  46. build() {
  47. Column() {
  48. RichEditor({ controller: this.controller })
  49. .width('100%')
  50. .borderWidth(1)
  51. .borderColor(Color.Black)
  52. .onReady(() => {
  53. this.controller.addTextSpan('有序排队')
  54. })
  55. .customKeyboard(this.showKeyboard ? this.CustomKeyboardBuilder() : undefined)
  56. Button('切换系统键盘与自定义键盘').onClick((event: ClickEvent) => {
  57. this.showKeyboard = ! this.showKeyboard
  58. })
  59. }
  60. .height('100%')
  61. }
  62. }
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

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

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

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

本版积分规则

用户云卷云舒

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表