HarmonyOS鸿蒙Next中RichEditor实现“@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"替换图片功能,可以通过以下方案:
-
文本监听处理: 使用TextInputListener监听输入变化,当检测到"@“字符时,启动用户选择流程。可以使用正则表达式匹配”@xxx"模式。
-
内容替换: 当用户选择完成后,使用RichEditor的insertImage()方法插入对应的用户头像图片,建议将用户ID作为图片的metadata存储。
-
删除处理: 通过注册KeyEvent监听器,特别是针对删除键(KeyCode.DEL)的事件:
- 检查光标位置是否在图片前
- 获取图片关联的用户数据
- 执行整体删除(图片+关联文本)
- 数据关联: 建议使用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) {
// 处理用户提及删除
}
}
});
注意事项:
- 图片建议使用固定尺寸保持UI一致性
- 考虑在网络图片时添加加载状态
- 对于长文本中的大量提及要做好性能优化
这种实现方式既保持了文本输入的流畅性,又能准确关联用户数据。