赞
踩
RichEditor是支持图文混排和文本交互式编辑的组件,在我们使用的APP中是很常见的,比如评论区编辑内容发布、对话框或者聊天室。下面列举一些遇到的场景需求:
场景一:基于文字图片以及@信息的好友评论
场景二:右下角的剩余字数
场景三:评论中携带所@的用户的附属信息
场景四:文本选择区域发生变化或编辑状态下光标位置发生变化回调
场景五:自由切换系统键盘和自定义键盘。
效果图
方案
1、通过addTextSpan来添加文字,2、通过addImageSpan来添加图片3、通过addBuilderSpan来实现一段内容光标不可插入的效果4、addTextSpan等支持gesture等手势操作,比如onClick点击和onLongPress长按事件
核心代码
1、由于RichEditor是支持图文混排的,所以RichEditor里面的内容也就是由Text和Image组成的,分别通过addTextSpan和addImageSpan添加,而且还可以设置字体和图片样式,如下代码1:
@Entry @Component struct getSpans { editorController = new RichEditorController() build() { Column() { RichEditor({ controller: this.editorController }) .width('100%') .backgroundColor(Color.Yellow) .onReady(() => { this.editorController.addImageSpan($r("app.media.icon"), { imageStyle: { size: ["100px", "100px"] } }) this.editorController.addTextSpan('男生女生向前冲', { style: { fontColor: Color.Blue, fontSize: 30 } }) }) Button('getSpans-图片').onClick((event: ClickEvent) => { let getSpans = this.editorController.getSpans({ start: 0 }) console.log('getSpans0' + JSON.stringify(getSpans[0])) // 必须进行强转才能获取文字信息或者图片信息 let span0 = getSpans[0] as RichEditorTextSpanResult console.log('图片相关的信息: ' + JSON.stringify(span0)) }) Button('getSpans-文字').onClick((event: ClickEvent) => { let getSpans = this.editorController.getSpans({ start: 0 }) console.log('getSpans1' + JSON.stringify(getSpans[1])) let span1 = getSpans[1] as RichEditorImageSpanResult console.log('文字相关的信息: ' + JSON.stringify(span1)) }) } } }
2、在常见的评论区艾特好友时,会将“@华为官方客服”视作一个整体,光标无法插入其中,且第一次按删除键时整体会高亮选中,第二次再按删除键才会删除。**需要注意的是,如果使用的全局@Builder,则需要配合bind(this)使用。**后续也可以通过事件阻止“即RichEditor控件ClickEvent/TouchEvent支持preventDefault”。
@Entry @Component struct BuilderSpan { editorController = new RichEditorController() @Builder At(str: string) { Stack() { Text('@' + str).fontColor(Color.Blue) } } build() { Column() { RichEditor({ controller: this.editorController }) .width('100%') .height(50) .backgroundColor(Color.Yellow) .onReady(() => { this.editorController.addBuilderSpan(() => { this.At('华为官方客服') }) this.editorController.addTextSpan('!!!') }) } } }
3、发微博的时候可以输入表情、超链接、文字等一起的内容
代码3:
@Component struct Index { @State message: string = '#超话社区#'; controller: RichEditorController = new RichEditorController(); @State show: boolean = false; build() { Column() { RichEditor({controller: this.controller}) .height(56) .width("90%") .borderStyle(BorderStyle.Solid) .borderColor(Color.Black) .borderWidth(1) .onReady(() => { }) Button('输入表情').onClick((event: ClickEvent) => { this.controller.addImageSpan($r('app.media.app_icon'), { imageStyle: { size: ["80px", "80px"] } }) }) Button('超链接').onClick((event: ClickEvent) => { this.controller.addTextSpan(this.message, { offset: this.controller.getCaretOffset(), style: { fontColor: Color.Orange, fontSize: 16 }, gesture: { onClick: () => { console.log('要跳转链接了哦') }, onLongPress: () => { console.log('我被长按了') } } }) this.controller.setCaretOffset(this.controller.getCaretOffset() + this.message.length) }) } .width('100%') } }
效果图
方案
使用overlay浮层,显示“0/20”字数提示符在组件的右下角。再通过aboutToIMEInput回调(输入法输入内容前),获取插入的文本偏移位置,对输入内容进行限制。
核心代码
import promptAction from '@ohos.promptAction'; @Entry @Component struct MaxDemo { @State message: string = '蜡笔小新'; controller: RichEditorController = new RichEditorController(); @State getContentLength: number = 0; @State BOnSt:promptAction.ShowToastOptions = {'message': '已超出内容最大限制.'} build() { Column() { RichEditor({ controller: this.controller }) .height(100) .borderWidth(1) .borderColor(Color.Red) .width("100%") .overlay(this.getContentLength + "/20", { align: Alignment.BottomEnd }) .aboutToIMEInput((value: RichEditorInsertValue) => { console.log("insertOffset:" + JSON.stringify(value.insertValue)) // 插入的文本偏移位置。 if (this.getContentLength < 20) { this.getContentLength = this.getContentLength + value.insertValue.length console.log('实时的内容长度:' + this.getContentLength) return true } promptAction.showToast(this.BOnSt) return false }) .aboutToDelete((value: RichEditorDeleteValue) => { console.log('删除:' + JSON.stringify(value)) this.getContentLength = this.getContentLength - value.length return true }) } .width('100%') } }
效果图
方案
使用HashMap的set向HashMap中添加或更新一组数据,使用get方法获取指定key所对应的value。
核心代码
@Entry @Component struct SameNameDemo { controller: RichEditorController = new RichEditorController(); @Builder At(str: string) { Stack() { Text('@' + str).fontColor(Color.Blue) } .onClick(() => { // 添加不同的身份信息 const hashMap: HashMap<string, number> = new HashMap(); hashMap.set("friend1", 123); let result = hashMap.get("friend1"); console.log('result: ' + result) }) } build() { Column() { RichEditor({ controller: this.controller }) .height(100) .borderWidth(1) .borderColor(Color.Red) .width("100%") Button('好友1').onClick((event: ClickEvent) => { this.controller.addBuilderSpan(() => { this.At('华为官方客服') }) }) Button('好友2').onClick((event: ClickEvent) => { this.controller.addBuilderSpan(() => { this.At('华为官方客服') }) }) } .width('100%') } }
效果图
方案
使用RichEditor组件在API 12支持的新接口 onSelectionChange,在文本选择区域发生变化或编辑状态下光标位置发生变化时触发该回调。光标位置发生变化回调时,选择区域的起始位置等于终止位置(即start = end)。
核心代码
@Entry @Component struct Index { @State message: string = '蜡笔小新'; controller: RichEditorController = new RichEditorController(); @State show: boolean = false; build() { Column() { RichEditor({controller: this.controller}) .defaultFocus(true) .padding(0) .height(56) .width("90%") .borderStyle(BorderStyle.Solid) .borderColor(Color.Black) .borderWidth(1) .padding({left: 10}) .onReady(() => { this.controller.addTextSpan(this.message, { offset: this.controller.getCaretOffset(), style: { fontColor: Color.Orange, fontSize: 16 } }) this.controller.setCaretOffset(this.controller.getCaretOffset() + this.message.length) }) .onSelectionChange((value:RichEditorRange) => { console.log('光标位置改变了') console.log('start: ' + value.start) console.log('end: ' + value.end) }) } .width('100%') } }
效果图
方案
使用RichEditor的属性customKeyboard控制切换系统键盘还是自定义键盘,添加表情使用addImageSpan,删除内容使用deleteSpans,并通过获取光标所在位置进行删除。
核心代码
@Entry @Component struct Index { @State message: string = 'Hello World'; controller = new RichEditorController() @State showKeyboard:boolean = false; private listData: (string | number | Resource)[] = [ $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'), $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'), $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'), $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'), $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'), ]; // 自定义键盘组件 @Builder CustomKeyboardBuilder() { Column() { Text('自定义表情键盘') .fontSize(25) .fontWeight(900) Grid() { ForEach(this.listData, (item: string | number | Resource) => { GridItem() { if (typeof item !== 'number' && typeof item !== 'string') { Image(item) .width(30).onClick(() => { this.controller.addImageSpan(item, { imageStyle: { size: ['110px', '110px'] } }) }) } } }) }.columnsGap(10).rowsGap(10).padding(5) Row() { Image($r('app.media.img_7')) .width(30) .onClick(() => { this.controller.deleteSpans({start: this.controller.getCaretOffset() - 1, end: this.controller.getCaretOffset()}) }) } .width('100%') .justifyContent(FlexAlign.End) .margin({ bottom: 40 }) } .borderColor(Color.Gray) .borderWidth(5) } build() { Column() { RichEditor({ controller: this.controller }) .width('100%') .borderWidth(1) .borderColor(Color.Black) .onReady(() => { this.controller.addTextSpan('有序排队') }) .customKeyboard(this.showKeyboard ? this.CustomKeyboardBuilder() : undefined) Button('切换系统键盘与自定义键盘').onClick((event: ClickEvent) => { this.showKeyboard = ! this.showKeyboard }) } .height('100%') } }
有很多小伙伴不知道学习哪些鸿蒙开发技术?不知道需要重点掌握哪些鸿蒙应用开发知识点?而且学习时频繁踩坑,最终浪费大量时间。所以要有一份实用的鸿蒙(HarmonyOS NEXT)学习路线与学习文档用来跟着学习是非常有必要的。
针对一些列因素,整理了一套纯血版鸿蒙(HarmonyOS Next)全栈开发技术的学习路线,包含了鸿蒙开发必掌握的核心知识要点,内容有(ArkTS、ArkUI开发组件、Stage模型、多端部署、分布式应用开发、WebGL、元服务、OpenHarmony多媒体技术、Napi组件、OpenHarmony内核、OpenHarmony驱动开发、系统定制移植等等)鸿蒙(HarmonyOS NEXT)技术知识点。
gitee.com/MNxiaona/733GH
gitee.com/MNxiaona/733GH
1.基本概念
2.构建第一个ArkTS应用
3.……
gitee.com/MNxiaona/733GH
1.应用基础知识
2.配置文件
3.应用数据管理
4.应用安全管理
5.应用隐私保护
6.三方应用调用管控机制
7.资源分类与访问
8.学习ArkTS语言
9.……
1.Ability开发
2.UI开发
3.公共事件与通知
4.窗口管理
5.媒体
6.安全
7.网络与链接
8.电话服务
9.数据管理
10.后台任务(Background Task)管理
11.设备管理
12.设备使用信息统计
13.DFX
14.国际化开发
15.折叠屏系列
16.……
gitee.com/MNxiaona/733GH
gitee.com/MNxiaona/733GH