HarmonyOS鸿蒙Next中RichEditor实现“@xxx”替换成图片使用的功能

我想用HarmonyOS鸿蒙Next RichEditor实现“@xxx”替换成图片功能,需要在删除的时候监听键盘的删除键,同时@XXX 的图片可以对应到具体用户

4 回复

【背景知识】

  • RichEditor添加图片内容可以使用addImageSpan,由于该API是同步方法,网络图片加载是异步过程,直接传入网络URL可能导致图片无法立即加载显示,无法即时获取到图片尺寸信息进行布局计算,故不建议直接添加网络图片。
  • 可以使用http将网络图片下载到本地,然后调用image.createImageSource方法创建图片资源,最后调用addImageSpan添加图片。

【解决方案】

  • 方案一:若网络图片资源加载正常且性能表现可接受,可直接使用网络图片,示例代码如下:
@Entry
@Component
struct Index9 {
  controller: RichEditorController = new RichEditorController()
  options: RichEditorOptions = { controller: this.controller }
  build() {
    Column() {
      Column() {
        RichEditor(this.options)
          .onReady(() => {
            this.controller.addTextSpan('点击按钮在此处添加image。', {
              style: {
                fontColor: Color.Black,
                fontSize: 15
              }
            })
          })
          .width(300)
          .height(100)
        Button('addImageSpan', {
          buttonStyle: ButtonStyleMode.NORMAL
        })
          .height(30)
          .fontSize(13)
          .onClick(() => {
            this.controller.addImageSpan("http://www.baidu.com/img/bdlogo.png", {
              imageStyle: {
                size: ["57px", "57px"]
              }
            })
          })
      }.width('100%')
    }.height('100%')
  }
}
  • 方案二:RichEditor添加图片前先做预处理,将网络图片下载下来赋值给一个状态变量pixelMap,最后通过richEditorController.addImageSpan加载下载的网络图片。示例代码如下:
import { http } from '@kit.NetworkKit';
import { image } from '@kit.ImageKit';

@Entry
@Component
struct Index9 {
  controller: RichEditorController = new RichEditorController()
  options: RichEditorOptions = { controller: this.controller }
  pixelMap: PixelMap | null = null
  
  async loadNetworkImage(url: string): Promise<void> {
    let data = await http.createHttp().request(url);
    let imageBuffer: ArrayBuffer = data.result as ArrayBuffer;
    this.pixelMap = await image.createImageSource(imageBuffer).createPixelMap();
  }
  
  aboutToAppear(): void {
    this.loadNetworkImage("http://www.baidu.com/img/bdlogo.png")
  }
  
  build() {
    Column() {
      Column() {
        RichEditor(this.options)
          .onReady(() => {
            this.controller.addTextSpan('点击按钮在此处添加image。')
          })
          .width(300)
          .height(100)
        Button('addImageSpan')
          .height(30)
          .fontSize(13)
          .onClick(() => {
            this.controller.addImageSpan(this.pixelMap, {
              imageStyle: {
                size: ["57px", "57px"]
              }
            });
          })
      }.width('100%')
    }.height('100%')
  }
}

更多关于HarmonyOS鸿蒙Next中RichEditor实现“@xxx”替换成图片使用的功能的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


经验证,参考以下demo可以实现您的需求,您尝试下~

[@xinyansoft/oh-topic-editor](https://ohpm.openharmony.cn/#/cn/detail/)

在HarmonyOS鸿蒙Next中,实现RichEditor的“@xxx”替换成图片功能,可以通过自定义TextWatcher监听输入内容,当检测到“@xxx”格式时,使用ImageSpan将文本替换为图片。具体步骤包括:监听输入变化,匹配“@xxx”模式,获取对应图片资源,创建ImageSpan实例,最后使用SpannableString替换文本。注意处理光标位置和图片大小适配。

在HarmonyOS Next中实现RichEditor的"@xxx"替换图片功能,可以通过以下方案:

  1. 文本监听处理: 使用TextInputListener监听输入变化,当检测到"@“字符时,启动用户选择流程。可以使用正则表达式匹配”@xxx"模式。

  2. 内容替换: 当用户选择完成后,使用RichEditor的insertImage()方法插入对应的用户头像图片,建议将用户ID作为图片的metadata存储。

  3. 删除处理: 通过注册KeyEvent监听器,特别是针对删除键(KeyCode.DEL)的事件:

  • 检查光标位置是否在图片前
  • 获取图片关联的用户数据
  • 执行整体删除(图片+关联文本)
  1. 数据关联: 建议使用Span机制,为每个替换图片附加用户信息的Span,便于后续处理。

关键代码片段示例:

// 监听输入
richEditor.addTextObserver((text, start, end) => {
  if(text.endsWith("@")) {
    showUserPicker();
  }
});

// 插入图片
function insertUserMention(user: User) {
  const image = new PixelMap(...);
  richEditor.insertImage(image, {
    metadata: {userId: user.id}
  });
}

// 处理删除
richEditor.setKeyEventListener((event) => {
  if(event.keyCode === KeyCode.DEL) {
    const cursorPos = richEditor.getCursorPosition();
    const span = richEditor.getSpanAtPosition(cursorPos);
    if(span?.metadata?.userId) {
      // 处理用户提及删除
    }
  }
});

注意事项:

  1. 图片建议使用固定尺寸保持UI一致性
  2. 考虑在网络图片时添加加载状态
  3. 对于长文本中的大量提及要做好性能优化

这种实现方式既保持了文本输入的流畅性,又能准确关联用户数据。

回到顶部