会话页面自定义
消息点击事 件
为了避免内存泄露,请将监听保存,在必要的时候移除
MessageClickListener 的所有方法均为可选方法,可以按需实现,此处为了方便展示,将所有方法都做了默认实现
- 从
1.4.3
版本开始,onMessageClick
支持语音消息。 - 从
1.4.3
版本开始,所有方法均增加Context
、ClickEvent/GestureEvent
参数。
let msgClickListener : MessageClickListener = {
onMessagePortraitClick: (message: Message, userId: string, context?: Context, event?: ClickEvent) => {
// 消息头像点击事件
// true 由 App 处理该事件,SDK 不再处理。false 由 SDK 处理
return false;
},
onMessagePortraitLongClick: (message: Message, user: UserInfoModel, context?: Context, event?: GestureEvent) => {
// 消息头像长按事件
// true 由 App 处理该事件,SDK 不再处理。false 由 SDK 处理
return false;
},
onMessageClick: (message: Message, context?: Context, event?: ClickEvent) => {
// 消息点击事件
// true 由 App 处理该事件,SDK 不再处理。false 由 SDK 处理
return false;
},
onMessageLongClick: (message: Message, context?: Context, event?: GestureEvent) => {
// 消息长按事件
// true 由 App 处理该事件,SDK 不再处理。false 由 SDK 处理
return false;
},
onMessageRecallEditClick: (message: Message, context?: Context, event?: ClickEvent) => {
// 消息撤回编辑事件
// true 由 App 处理该事件,SDK 不再处理。false 由 SDK 处理
return false;
},
onMessageLinkClick: (message: Message, url: string, context?: Context, event?: ClickEvent) => {
// 文本消息超链接点击事件
// true 由 App 处理该事件,SDK 不再处理。false 由 SDK 处理
return false;
},
onMessageEmailClick: (message: Message, email: string, context?: Context, event?: ClickEvent) => {
// 文本消息 email 点击事件
// true 由 App 处理该事件,SDK 不再处理。false 由 SDK 处理
return false;
},
onMessagePhoneClick: (message: Message, phone: string, context?: Context, event?: ClickEvent) => {
// 文本消息手机号点击事件
// true 由 App 处理该事件,SDK 不再处理。false 由 SDK 处理
return false;
},
}
RongIM.getInstance().conversationService().addMessageClickListener(msgClickListener);
增加消息气泡的长按事件
let msgLongClickAction :ItemLongClickAction<Message> = {
obtainTitle: (context: Context, data: Message): string | Resource => {
return "自定义的消息长按事件"
},
onClick: (context: Context, data: Message): void => {
promptAction.showToast({message : "点击了自定义的消息长按事件"})
},
onFilter: (data: Message): boolean => {
// 是否显示该长按事件?true 显示;false 不显示
// 开发者可以根据 Message 对象的会话类型或者消息类型决定是否显示
return true;
},
// 自定义的消息长按事件 Id,相同的 Id 的长按事件只会增加一次
actionId: 'CustomMessageActionId'
}
RongIM.getInstance().conversationService().addMessageItemLongClickAction(msgLongClickAction);
修改消息气泡的UI配置
IMKit 从 1.4.3
版本开始支持修改消息气泡的UI配置。支持设置的属性:边框圆角大小、边框色、背景色。
注意:仅支持初始化前的配置,若初始化后开发者设置,则不会生效。
修改边框圆角大小示例
边框圆角大小支持按消息方向来设置:
- 设置/获取接收的消息气泡边框圆角大小:
setReceivedMessageBorderRadius
、getReceivedMessageBorderRadius
。 - 设置/获取发送的消息气泡边框圆角大小:
setSentMessageBorderRadius
、getSentMessageBorderRadius
。
let config = RongIM.getInstance().conversationService().getConversationConfig();
let receivedMessageBorderRadius: BorderRadiuses = {
topLeft: 4,
topRight: 8,
bottomLeft: 8,
bottomRight: 8
}
config.setReceivedMessageBorderRadius(receivedMessageBorderRadius);
RongIM.getInstance().conversationService().setConversationConfig(config);
修改边框色示例
边框色支持按消息方向来设置:
- 设置/获取接收的消息气泡边框色:
setReceivedMessageBorderColor
、getReceivedMessageBorderColor
。 - 设置/获取发送的消息气泡边框色:
setSentMessageBorderColor
、getSentMessageBorderColor
。
- 仅修改文本消息类型的边框色为灰色,其他消息类型不修改
let config = RongIM.getInstance().conversationService().getConversationConfig();
config.setReceivedMessageBorderColor("RC:TxtMsg", Color.Gray);
RongIM.getInstance().conversationService().setConversationConfig(config);
- 修改全部消息类型的边框色为灰色
let config = RongIM.getInstance().conversationService().getConversationConfig();
config.setReceivedMessageBorderColor("", Color.Gray);
RongIM.getInstance().conversationService().setConversationConfig(config);
- 修改文本消息类型的边框色为灰色,同时修改其余消息类型的边框色为蓝色,示例(可以不分顺序调用)
let config = RongIM.getInstance().conversationService().getConversationConfig();
config.setReceivedMessageBorderColor("RC:TxtMsg", Color.Gray);
config.setReceivedMessageBorderColor("", Color.Blue);
RongIM.getInstance().conversationService().setConversationConfig(config);
修改背景色示例
背景色支持按消息方向来设置:
- 设置/获取接收的消息气泡背景色:
setReceivedMessageBackgroundColor
、getReceivedMessageBackgroundColor
。 - 设置/获取发送的消息气泡背景色:
setSentMessageBackgroundColor
、getSentMessageBackgroundColor
。
- 仅修改文本消息类型的背景色为灰色,其他消息类型不修改
let config = RongIM.getInstance().conversationService().getConversationConfig();
config.setReceivedMessageBackgroundColor("RC:TxtMsg", Color.Gray);
RongIM.getInstance().conversationService().setConversationConfig(config);
- 修改全部消息类型的背景色为灰色
let config = RongIM.getInstance().conversationService().getConversationConfig();
config.setReceivedMessageBackgroundColor("", Color.Gray);
RongIM.getInstance().conversationService().setConversationConfig(config);
- 修改文本消息类型的背景色为灰色,同时修改其余消息类型的背景色为蓝色,示例(可以不分顺序调用)
let config = RongIM.getInstance().conversationService().getConversationConfig();
config.setReceivedMessageBackgroundColor("RC:TxtMsg", Color.Gray);
config.setReceivedMessageBackgroundColor("", Color.Blue);
RongIM.getInstance().conversationService().setConversationConfig(config);
增加“更多”的点击事件
长按消息,点击“更多”按钮之后,底部会有个更多的功能栏,往里面增加点击事件。
let msgMoreAction : MessageMoreAction = {
actionId: 'message_more_forward',// 动作 Id
location: 100, // 按钮将放置在底部,根据 location 值,按照从小到大的顺序依次向右排列。
icon: $r("app.media.rc_message_more_forward"), // 图标
onClick: (context: Context, data: Message[]): boolean => {
// 处理自定义的点击事件
// return true :聊天页面依旧处于多选状态
// return false : 聊天页面退出多选状态
promptAction.showToast({message : "点击了聊天页面底部的更多按钮"});
return true
},
onFilter: (data: Message[]): boolean => {
// 是否显示该按钮,true 显示,false 不显示
return true;
}
}
RongIM.getInstance().conversationService().addMessageMoreAction(msgMoreAction)
增加 + 号扩展栏插件
实现插件
import { IBoardPlugin } from '@rongcloud/imkit';
import { ConversationIdentifier } from '@rongcloud/imlib';
import { promptAction } from '@kit.ArkUI';
/**
* 自定义插件
*/
export class CustomInfoMessagePlugin implements IBoardPlugin {
/**
* 插件名,用来判断插件唯一标识。如果不设置则无法查找、替换操作
* @returns 插件名
* @version 1.4.3 新增
*/
pluginName(): string {
return CameraPluginName
}
/**
* 返回插件的标题
* @param context 上下文
* @returns 标题
*/
obtainTitle(context: Context): string | Resource {
return "自定义小灰条消息"
}
/**
* 返回插件的图片
* @param context 上下文
* @returns 图片
*/
obtainImage(context: Context): Resource {
return $r("app.media.startIcon");
}
/**
* 插件的点击事件
* @param context 上下文
*/
onClick(context: Context, conId: ConversationIdentifier): void {
if (!conId) {
return;
}
// 处理具体的点击事件
// 开发者按照实际情况处理
promptAction.showToast({ message: '点击了自定义插件' })
}
/**
* 是否在会话中显示该插件
* @param conId 会话标识
* @returns 是否显示,true 显示;false 不显示
*/
onFilter(conId: ConversationIdentifier): boolean {
return true;
}
}
内置插件说明
IMKit 内置插件列表如下所示。其中位置插件 SDK 仅定义,实际需要 App 侧来实现。
插件 | 插件名称 | 说明 |
---|---|---|
图片插件 | ImagePlugin | ImagePluginName "RC:ImagePlugin" |
小视频插件 | CameraPlugin | CameraPluginName "RC:CameraPlugin" |
文件插件 | FilePlugin | FilePluginName "RC:FilePlugin" |
阅后即焚插件 | DestructPlugin | DestructPluginName "RC:DestructPlugin" |
位置插件 | LocationPlugin | LocationPluginName "RC:LocationPlugin" |
将插件放到扩展栏里面
需要在聊天页面出现前调用
添加插件
let customInfoMessagePlugin = new CustomInfoMessagePlugin();
RongIM.getInstance().conversationService().addBoardPlugin(customInfoMessagePlugin);
将插件放到指定位置
let index : number = 0
let customInfoMessagePlugin = new CustomInfoMessagePlugin();
RongIM.getInstance().conversationService().insertBoardPlugin(index, customInfoMessagePlugin);
替换指定位置的插件,如果没有对应的索引,会将插件放到最后
let index : number = 0
let customInfoMessagePlugin = new CustomInfoMessagePlugin();
RongIM.getInstance().conversationService().replaceBoardPlugin(index, customInfoMessagePlugin);
移除特定的插件
let customInfoMessagePlugin = new CustomInfoMessagePlugin();
RongIM.getInstance().conversationService().removeBoardPlugin(customInfoMessagePlugin);
根据插件名移除特定的插件
- 自定义插件实现
pluginName()
接口返回插件名,便可以通过removeBoardPluginByName
来移除插件。 - 系统插件均实现了
pluginName()
,可以参照上面表格中插件对应的名字,通过removeBoardPluginByName
来移除插件。
RongIM.getInstance().conversationService().removeBoardPluginByName("插件名");
清空当前的插件。
注意:该接口只能清空通过 addBoardPlugin
、insertBoardPlugin
、replaceBoardPlugin
添加的插件。通过动态配置扩展面板插件可以做到彻底清空。
RongIM.getInstance().conversationService().clearBoardPlugin();
动态配置扩展面板插件
如果应用程序需要动态添加、删除扩展面板插件,或者调整插件位置,建议通过创建自定义的扩展面板配置实现这些自定义需求。
实现 IExtensionConfig,创建自定义的扩展面板配置类,重写 getPluginModules() 方法。您可以增加或删除扩展项,也可以调整各插件的位置。
let mCustomExtensionConfig: IExtensionConfig = {
getPluginModules: (convId: ConversationIdentifier) => {
// 获取当前的插件配置
let config = RongIM.getInstance().conversationService().getExtensionConfig()
// 根据插件配置获取对应会话标识的插件
let currentPlugins = config.getPluginModules(ConversationIdentifier.createWith2(ConversationType.Private, "TargetID"))
let plugins: ArrayList<IBoardPlugin> = new ArrayList<IBoardPlugin>()
// 这里示范了去除文件插件的操作。当然也可以根据 pluginName 来重新排序插件等操作。
for (let plugin of currentPlugins) {
if (plugin.pluginName && plugin.pluginName() !== FilePlugin.name) {
plugins.add(plugin)
}
}
// 添加业务侧自定义的插件
plugins.add(new TestPlugin1())
plugins.add(new TestPlugin2())
return plugins
}
}
SDK 初始化之后,调用以下方法设置自定义的输入配置,SDK 会根据此配置展示扩展面板。
RongIM.getInstance().conversationService().setExtensionConfig(mCustomExtensionConfig)
获取当前插件配置
let config = RongExtensionManager.getInstance().getExtensionConfig()
// 根据 ConversationIdentifier 获取对应的插件列表
let convId: ConversationIdentifier
let pluginModules = config.getPluginModules(convId)
消息头像圆角控制
可以通过下面的代码配置消息头像圆角控制,需要在会话页面展示前设置。
let config = RongIM.getInstance().conversationService().getConversationConfig();
config.setMessageAvatarStyle(AvatarStyle.Cycle);
RongIM.getInstance().conversationService().setConversationConfig(config);
修改消息可撤回的最大时间
IMKit 默认允许在消息发送后 180 秒内撤回。您可以通过全局配置调整该上限,需要在会话页面展示前设置。
let config = RongIM.getInstance().conversationService().getConversationConfig()
config.setMaxRecallDuration(180)
RongIM.getInstance().conversationService().setConversationConfig(config)
修改撤回后可重新编辑的时间
IMKit 默认允许在消息撤回后 30 秒内可点击重新编辑,仅文本消息支持撤回再编辑。您可以通过全局配置调整该上限,需要在会话页面展示前设置。
let config = RongIM.getInstance().conversationService().getConversationConfig()
config.setMaxEditableDuration(30)
RongIM.getInstance().conversationService().setConversationConfig(config)
文本消息字体高亮颜色
IMKit 默认允许配置 SDK 内置文本消息中的url 手机号 @信息等高亮字体颜色,默认黑色。您可以通过全局配置调整,需要在会话页面展示前设置。
let config = RongIM.getInstance().conversationService().getConversationConfig()
config.setStyleFontColor(Color.Blue)
RongIM.getInstance().conversationService().setConversationConfig(config)
设置文件消息的文件类型图标
IMKit 默认允许配置 SDK 内置文件消息的文件类型图标。您可以通过全局配置调整,需要在会话页面展示前设置。
可以通过 setFileMessageIcons
覆盖默认配置。
let config = RongIM.getInstance().conversationService().getConversationConfig()
//设置图片
let iconsMap: Map<string, Resource> = new Map<string, Resource>();
//覆盖sdk默认图片
iconsMap.set('doc', $r("app.media.doc_icon"));
iconsMap.set('mp3', $r("app.media.mp3_icon"));
iconsMap.set('pdf', $r("app.media.pdf_icon"));
iconsMap.set('rmvb', $r("app.media.rmvb_icon"));
iconsMap.set('default', $r("app.media.rc_default_icon"));
config.setFileMessageIcons(iconsMap);
RongIM.getInstance().conversationService().setConversationConfig(config)
可以通过 getFileMessageIcons
获取文件消息内的文件类型图标map。
let config = RongIM.getInstance().conversationService().getConversationConfig()
config.getFileMessageIcons();
可以通过 getFileMessageIcon
获取文件消息内的文件类型图标,如果找不到,返回 sdk 内置的默认图标。
let config = RongIM.getInstance().conversationService().getConversationConfig()
config.getFileMessageIcon('doc');
修改消息重发开关
IMKit 从 1.4.3
版本开始支持消息发送失败时自动消息重发。
为了跟 iOS
、Android
端现有逻辑保持一致,该配置默认值为为 true
。
从 1.4.3
以下版本升级的客户,会改变默认行为,如果不想消息重发,需要主动设置为 false
。
let config = RongIM.getInstance().conversationService().getConversationConfig()
config.setEnableResendMessage(false)
RongIM.getInstance().conversationService().setConversationConfig(config)
会话页面事件
IMKit 提供了会话页面事件监听器 ConversationEventListener
,可监听会话页面中输入@时跳转用户列表选择用户事件、当输入状态变化时的事件。需要在会话页面展示前设置。
import {
ConversationEventListener
} from '@rongcloud/imkit';
export interface ConversationEventListener {
/**
* 输入@时,跳转用户列表选择用户
* @param select 选中的用户信息
*/
onInputMention?: (select: (user: UserInfoModel) => void) => void;
/**
* 当输入状态变化时
* @param isEditing
*/
onEditChange?: (isEditing: boolean) => void;
}
使用 RongIM
的 addConversationEventListener
、removeConversationEventListener
方法添加或者监听器。
建议添加监听后,在合适的时机移除,避免内存泄露。如果在页面中监听,建议在 aboutToAppear
调用,在 aboutToDisappear
移除监听。
// 添加监听器
RongIM.getInstance().conversationService().addConversationEventListener(listener);
// 移除监听器
RongIM.getInstance().conversationService().removeConversationEventListener(listener);