赞
踩
本示例主要介绍如何在聊天信息中加入表情图片。通过使用CustomDialog创建表情键盘对话框,使用RichEdit接收所选表情的ImageSpan。在发送信息时将图片和文字消息分别通过ImageSpan、Span加入到消息列表中,显示的时候将消息列表中的ImageSpan、Span包裹在Text中进行显示。
使用说明
1.进入页面,在底部输入框中输入文字,点击输入框右边的表情图片按钮弹出表情键盘,在表情键盘中选择表情图片后点击发送,在聊天对话框中会显示聊天文字以及表情。
实现思路
1.在CustomDialog中通过Grid创建表情键盘,选中表情图片后,将表情通过imageSpan的方式加到RichEditor输入框中。
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)
2.点击发送时,通过RichEditorController的getSpans方法,将聊天信息中ImageSpan、Span分别push到要发送的信息的spanItems中。
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);
3.在聊天对话框中通过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 }); } } }) }
4.将聊天信息的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库中日志打印模块进行日志打印。
https://docs.qq.com/doc/DZVVBYlhuRkZQZlB3
https://docs.qq.com/doc/DZVVBYlhuRkZQZlB3
https://docs.qq.com/doc/DZVVBYlhuRkZQZlB3
https://docs.qq.com/doc/DZVVBYlhuRkZQZlB3
1.基本概念
2.构建第一个ArkTS应用
3.……
https://docs.qq.com/doc/DZVVBYlhuRkZQZlB3
1.应用基础知识
2.配置文件
3.应用数据管理
4.应用安全管理
5.应用隐私保护
6.三方应用调用管控机制
7.资源分类与访问
8.学习ArkTS语言
9.……
https://docs.qq.com/doc/DZVVBYlhuRkZQZlB3
1.Ability开发
2.UI开发
3.公共事件与通知
4.窗口管理
5.媒体
6.安全
7.网络与链接
8.电话服务
9.数据管理
10.后台任务(Background Task)管理
11.设备管理
12.设备使用信息统计
13.DFX
14.国际化开发
15.折叠屏系列
16.……
https://docs.qq.com/doc/DZVVkRGRUd3pHSnFG
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。