智能客服
你问我答,随时在线为你解决问题
要在文本框中实现图片与文字的组合场景,类似于文件符号图片加文件名的组合。
使用有如下诉求:
- .onSelectionChange((data) => {
- this.needNewSpan = false;
- // 根据光标位置获取对应Span信息
- let span = this.controller.getSpans(data);
- if (span.length != 0) {
- let spanLocation: number = span[0].spanPosition.spanIndex;
- let res = this.isCombinations(spanLocation);
- if (res) {
- // 判断是否是多选
- if (data.start != data.end) {
- // 判断是否是第一次调整多选位置
- if (!this.isSetSelection) {
- // 将组合全选
- this.isSetSelection = true;
- if (span[0].spanPosition.spanIndex == this.combinationsLocation[this.needUpdateCombinations][0]) {
- let spanText = this.controller.getSpans({ start: span[0].spanPosition.spanRange[1] + 1 });
- this.controller.setSelection(span[0].spanPosition.spanRange[0],
- spanText[0].spanPosition.spanRange[1]);
- } else {
- this.controller.setSelection(span[0].spanPosition.spanRange[0] - 1,
- span[0].spanPosition.spanRange[1]);
- }
- } else {
- this.isSetSelection = false;
- }
- } else {
- // 移动光标至组合末尾
- this.controller.setCaretOffset(span[0].spanPosition.spanRange[1]);
- this.needNewSpan = true;
- }
- }
- }
- })
- // 写入Span组合
- combinations(text: string, img: PixelMap | ResourceStr) {
- this.controller.addImageSpan(img, { imageStyle: { size: [20, 20], layoutStyle: { margin: { left: 5 } } } });
- this.controller.addTextSpan(text + ' ', { style: { fontColor: Color.Blue, fontSize: 18 } });
- }
- @Entry
- @Component
- struct Index4RichEditor {
- controller: RichEditorController = new RichEditorController();
- option: RichEditorOptions = { controller: this.controller };
- img: Resource = $r('app.media.startIcon');
- // 需要组合的Span记录
- combinationsLocation: Array<Array<number>> = [[0, 1], [3, 4], [6, 7], [8, 9], [11, 12]];
- // 当输入的文字处于组合末尾时,需要新建Span
- needNewSpan: boolean = false;
- // 是否需要更新组合Span记录
- needUpdateCombinations: number = 0;
- // 判断是否已经更新过选中区域
- isSetSelection: boolean = false;
-
- // 写入Span组合
- combinations(text: string, img: PixelMap | ResourceStr) {
- this.controller.addImageSpan(img, { imageStyle: { size: [20, 20], layoutStyle: { margin: { left: 5 } } } });
- this.controller.addTextSpan(text + ' ', { style: { fontColor: Color.Blue, fontSize: 18 } });
- }
-
- // 判断位置是否处于组合内
- isCombinations(spanLocation: number): boolean {
- for (let index = 0; index < this.combinationsLocation.length; index++) {
- if (spanLocation == this.combinationsLocation[index][0] || spanLocation === this.combinationsLocation[index][1]) {
- this.needUpdateCombinations = index;
- return true;
- } else if (spanLocation < this.combinationsLocation[index][1]) {
- return false;
- }
- }
- return false;
- }
-
- // 更新组合所处位置
- updateCombinationsLocation() {
- for (let index = this.needUpdateCombinations; index < this.combinationsLocation.length; index++) {
- this.combinationsLocation[index][0] += 1;
- this.combinationsLocation[index][1] += 1;
- }
- }
-
- build() {
- Column() {
- RichEditor(this.option)
- .onReady(() => {
- this.combinations('@PyLo', this.img);
- this.controller.addTextSpan('请来会议室领取礼品,清单如下');
- this.combinations('领取礼品清单', this.img);
- this.controller.addTextSpan(',请参考清单到指定会议室');
- this.combinations('身体健康', this.img);
- this.combinations('万事如意', this.img);
- this.controller.addImageSpan(this.img, { imageStyle: { size: [20, 20], objectFit: ImageFit.Contain } });
- this.combinations('体锻如武夫', this.img);
- this.controller.addImageSpan(this.img, { imageStyle: { size: [20, 20], objectFit: ImageFit.Contain } });
- })
- .onSelectionChange((data) => {
- this.needNewSpan = false;
- // 根据光标位置获取对应Span信息
- let span = this.controller.getSpans(data);
- if (span.length != 0) {
- let spanLocation: number = span[0].spanPosition.spanIndex;
- let res = this.isCombinations(spanLocation);
- if (res) {
- // 判断是否是多选
- if (data.start != data.end) {
- // 判断是否是第一次调整多选位置
- if (!this.isSetSelection) {
- // 将组合全选
- this.isSetSelection = true;
- if (span[0].spanPosition.spanIndex == this.combinationsLocation[this.needUpdateCombinations][0]) {
- let spanText = this.controller.getSpans({ start: span[0].spanPosition.spanRange[1] + 1 });
- this.controller.setSelection(span[0].spanPosition.spanRange[0],
- spanText[0].spanPosition.spanRange[1]);
- } else {
- this.controller.setSelection(span[0].spanPosition.spanRange[0] - 1,
- span[0].spanPosition.spanRange[1]);
- }
- } else {
- this.isSetSelection = false;
- }
- } else {
- // 移动光标至组合末尾
- this.controller.setCaretOffset(span[0].spanPosition.spanRange[1]);
- this.needNewSpan = true;
- }
- }
- }
- })
- .aboutToIMEInput((value: RichEditorInsertValue) => {
- if (this.needNewSpan) {
- // 处理键入文字时光标位于组合末尾,防止与组合内文字Span拼接
- this.controller.addTextSpan(value.insertValue, { offset: value.insertOffset });
- this.updateCombinationsLocation();
- return false;
- } else if (value.insertOffset === 0) {
- // 处理光标位于行首的特殊情况
- this.needUpdateCombinations = 0;
- this.updateCombinationsLocation();
- }
- return true;
- })
- .padding(6)
- .borderRadius(6)
- .backgroundColor('#d8d8d9')
- .width("100%")
- .height("30%");
- }
- .padding(6)
- .width("100%")
- .height("70%");
- }
- }
Q:为什么addBuilderSpan中信息数量过多的时候会出现当前行还未填充完毕就整体切换到下一行且无法分行?
A:目前addBuilderSpan所生成的Span仅作为一个元素使用,元素不可拆分,因此当前行不可容纳会自动换行且无法分行。
Q:部分图片是由本地HTML生成的,怎么添加到RichEditor里?
A:可以使用web组件加载本地HTML,再通过addBuilderSpan添加自定义布局到RichEditor里。
智能客服
你问我答,随时在线为你解决问题
合作咨询
我们的专家服务团队将竭诚为您提供专业的合作咨询服务
解决方案
精准高效的一站式服务支持,助力开发者商业成功