代码拉取完成,页面将自动刷新
本示例主要介绍如何在聊天信息中加入表情图片。通过使用CustomDialog创建表情键盘对话框,使用RichEdit接收所选表情的ImageSpan。在发送信息时将图片和文字消息分别通过ImageSpan、Span加入到消息列表中,显示的时候将消息列表中的ImageSpan、Span包裹在Text中进行显示。
使用说明
在CustomDialog中通过Grid创建表情键盘,选中表情图片后,将表情通过imageSpan的方式加到RichEditor输入框中。源码参考CustomFaceDialog.ets
Grid() {
// TODO: 性能知识点:使用ForEach组件循环渲染数据
ForEach(EmojiData, (item: EmojiModel) => {
GridItem() {
Image(item.imgSrc)
.width(FaceGridConstants.EMOJI_IMAGE_SIZE)
.height(FaceGridConstants.EMOJI_IMAGE_SIZE)
.onClick(() => {
// TODO 知识点:将表情热键添加到输入框中
this.controller.addImageSpan(item.imgSrc, {
imageStyle: { size: [this.imageSize, this.imageSize], verticalAlign: ImageSpanAlignment.CENTER }
});
})
}
})
}
.maxCount(GRID_MAX_COUNT)
点击发送时,通过RichEditorController的getSpans方法,将聊天信息中ImageSpan、Span分别push到要发送的信息的spanItems中。源码参考ChatWithExpression.ets的sendChatMsg方法
let msgBase = new MessageBase(true, USER_NAME_MYSELF, HEAD_IMAGE_MYSELF, this.msgMaxWidth);
// 获取发送信息
this.controllerRich.getSpans({
start: this.start,
end: this.end
}).forEach(item => {
if (typeof (item as RichEditorImageSpanResult)['imageStyle'] !== 'undefined') {
// TODO 知识点:处理imagespan信息
const imageMsg: ResourceStr | undefined = (item as RichEditorImageSpanResult).valueResourceStr;
if (imageMsg !== undefined) {
const spanItem: SpanItem = new SpanItem(SpanType.IMAGE, '', imageMsg.toString().substring(EMOJI_SRC_POS));
msgBase.spanItems.push(spanItem);
}
} else {
// TODO 知识点:处理文字span信息
const textMsg: string = (item as RichEditorTextSpanResult).value;
const spanItem: SpanItem = new SpanItem(SpanType.TEXT, textMsg, '');
msgBase.spanItems.push(spanItem);
}
})
logger.info(TAG, 'sendChatMsg spanItems:' + msgBase.spanItems.length.toString());
// 发送
if (msgBase.spanItems.length !== 0) {
this.textDetailData.pushData(msgBase);
this.msgNums = this.textDetailData.totalCount();
this.scroller.scrollToIndex(this.msgNums - 1);
this.controllerRich.deleteSpans();
this.controllerRich.setCaretOffset(-1);
}
this.customFaceDialogCtl.close();
this.isFaceDlgOpen = false;
this.marginBottomInput = 0;
focusControl.requestFocus(this.focusKey);
在聊天对话框中通过LazyForEach循环加载聊天信息。
// 聊天对话框
List({
scroller: this.scroller,
initialIndex: this.msgNums - 1
}) {
// 性能知识点:使用懒加载组件渲染数据。参考资料:https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/arkts-rendering-control-lazyforeach-0000001820879609
LazyForEach(this.textDetailData, (msg: MessageBase) => {
ListItem() {
if (msg.isSelf) {
MessageItemSelfView({ msg: msg });
} else {
MessageItemView({ msg: msg });
}
}
})
}
将聊天信息的SpanItems根据spanType在Text中分别包裹为ImageSpan跟Span。
// 聊天信息
Row() {
Text(undefined) {
// TODO: 性能知识点:使用ForEach组件循环渲染数据
ForEach(this.msg.spanItems, (item: SpanItem) => {
// TODO 知识点:分别使用ImageSpan、Span渲染图片、文字信息
if (item.spanType === SpanType.IMAGE) {
ImageSpan($rawfile(item.imgSrc as string))
.width($r('app.integer.chat_font_size'))
.height($r('app.integer.chat_font_size'))
.verticalAlign(ImageSpanAlignment.BOTTOM).objectFit(ImageFit.Cover)
} else if (item.spanType === SpanType.TEXT) {
Span(item.text)
}
})
}.constraintSize({
minHeight: $r('app.integer.chat_inline_height'),
maxWidth: this.msg.maxWidth
})
.textAlign(TextAlign.Start)
}
本示例使用了LazyForEach进行数据懒加载,同时搭配组件复用能力以达到性能最优效果。
chatwithexpression // har类型
|---view
| |---ChatWithExpression.ets // 视图层-表情聊天界面
|---constants
| |---ChatConstants.ets // 常量
|---model
| |---Emoji.ets // 表情资源
| |---Message.ets // 消息结构
| |---BasicDataSource.ets // 数据类型文件
|---components
| |---CustomFaceDialog.ets // 表情键盘
本实例依赖动态路由模块实现页面的动态加载。
本实例依赖har包-common库中日志打印模块进行日志打印。
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。