发送自定义消息
更新时间: 2025/09/11 14:15:56
网易云信 IM UIKit 内置了多种基本消息类型,包括文本、图片、语音、视频、文件等,可满足大部分即时通讯场景。当这些基础消息类型无法满足您的业务需求时,您可以使用自定义消息来扩展功能,例如实现电商订单卡片、红包、系统通知等。
发送自定义消息
实现自定义消息收发之前,您需先自行实现消息数据的封装和相关解析规则。IM UIKit 可按照您实现的封装和解析规则对消息进行处理,将消息返回给您的应用。
第一步:实现自定义消息类
创建自定义 Attachment
,需要继承 CustomAttachment
,并重写数据解析方法(parse
)、数据封装方法(packData
)以及序列化方法(toJsonStr
)。
- 必须提供无参构造方法: 自定义的
Attachment
必须提供一个无参数的构造方法,因为 IM UIKit 内部会通过反射方式创建对象。 - 必须调用父类构造方法传入类型: 在构造方法中,必须调用父类的构造方法并传入自定义消息类型值(建议从 1000 开始)。
Javapublic class CustomerSampleAttachment extends CustomAttachment {
// 定义消息类型常量,建议从1000开始
private static final int TYPE = 1002;
// 自定义消息解析后的值,本例代表自定义消息只有一个 String 类型的值
private String customerText;
// 必须提供无参构造方法,IM UIKit 内部会通过反射方式创建对象
public CustomerSampleAttachment() {
super(TYPE); // 调用父类构造方法并传入消息类型
}
// 重写数据解析方法,这里面数据以 JSONObject 格式进行传输
@Override
protected void parseData(JSONObject data) {
try {
this.customerText = data.getString("customer_message_key");
} catch (Exception exception) {
}
}
// 重写数据封装方法,将您需要传递的内容转换为 JSONObject 格式
@Override
protected JSONObject packData() {
JSONObject data = new JSONObject();
try {
data.put("customer_message_key", customerText);
} catch (Exception exception) {
}
return data;
}
public void setData(String data) {
this.customerText = data;
}
// 设置自定义消息的信息摘要,用于会话列表展示
@Override
public String getContent() {
return "您的自定义消息...";
}
// 将自定义数据序列化为JSON字符串
@NonNull
@Override
public String toJsonStr() {
try {
JSONObject map = new JSONObject();
map.put("type", TYPE);
map.put("data", packData());
return map.toString();
} catch (Exception e) {
e.printStackTrace();
return "";
}
}
}
第二步:增加自定义消息映射关系
在消息数据处理逻辑中,增加自定义消息的映射关系。所有自定义消息都会在 ChatCustomMsgFactory
中进行分发,SDK 将确定您的自定义消息是采用哪个 CustomAttachment
并进行处理。
Java// 在 IM UIKit 初始化后添加映射关系
ChatKitClient.addCustomAttach(1002, CustomerSampleAttachment.class);
第三步:创建并发送自定义消息
创建自定义消息需要先实例化自定义 Attachment
类,然后使用 createCustomMessage
方法创建 V2NIMMessage
对象,最后通过 ChatRepo.sendMessage
方法发送。
Java// 创建自定义 Attachment 对象
CustomerSampleAttachment customerAttachment = new CustomerSampleAttachment();
// 设置 Attachment 中的数据
customerAttachment.setData("your data");
// 将 Attachment 序列化为字符串
String attachStr = customerAttachment.toJsonStr();
// 创建用于发送的 V2NIMMessage
V2NIMMessage customMsg = V2NIMMessageCreator.createCustomMessage("这是一个自定义消息", attachStr);
// 获取会话ID
String conversationId = "your_conversation_id";
// 调用 ChatRepo 提供的发送接口
ChatRepo.sendMessage(customMsg, conversationId, null, new Callback<Void>() {
@Override
public void onResult(int code, Void result, Throwable exception) {
if (code == 0) {
// 消息发送成功
} else {
// 消息发送失败
}
}
});
注意事项
当通过服务端 API 发送自定义消息时,为确保客户端能够正确识别和解析不同类型的自定义消息,您需要按照特定格式构造 attachment
字段的 JSON 内容。自定义消息的 attachment
字段应遵循以下 JSON 格式:
JSON{
"type": 1002, //Integer,自定义消息类型标识,用于客户端区分不同类型的自定义消息,必须与客户端定义的类型保持一致
"data": { //JSON,对象自定义消息的业务数据载体,可包含任意自定义的键值对
"customer\_message\_key": "这是一条自定义消息"
}
}
自定义消息 UI 展示
若需要在会话界面将自定义消息按照您自定义的 UI 样式进行展示,请完成以下步骤。
实现自定义 ViewHolder
添加消息展示的 ViewHolder
,并使其继承 NormalChatBaseMessageViewHolder
。
若集成了通用版 UI 组件,需要使其继承 FunChatBaseMessageViewHolder
(通用版)。也可参考 FunChatTextMessageViewHolder
、FunChatImageMessageViewHolder
等已实现的代码逻辑。
Javapublic class CustomerSampleViewHolder extends NormalChatBaseMessageViewHolder {
private CustomerSampleViewBinding binding;
public CustomerSampleViewHolder(@NonNull ChatBaseMessageViewHolderBinding parent, int viewType) {
super(parent, viewType);
}
@Override
public void addViewToMessageContainer() {
// 创建自己的 layout 布局,例如 R.layout.item_custom_evaluation
binding = CustomerSampleViewBinding.inflate(LayoutInflater.from(parent.getContext()),
getContainer(), true);
}
@Override
public void bindData(ChatMessageBean message, ChatMessageBean lastMessage) {
super.bindData(message, lastMessage);
currentMessage = message;
// 获取自定义消息的 Attachment
CustomerSampleAttachment attachment = (CustomerSampleAttachment) message.getMessageData().getAttachment();
if (attachment == null) {
return;
}
// 根据 attachment 中的数据设置 ViewHolder 的 UI
// 例如:binding.myTextView.setText(attachment.getData());
}
}
自定义消息去除头像
需要在自定义消息的 ViewHolder
中重写 onCommonViewVisibleConfig
,在该方法中控制头像信息的显示。
Javaprotected void onCommonViewVisibleConfig(ChatMessageBean messageBean) {
baseViewBinding.otherUsername.setVisibility(View.GONE);
baseViewBinding.otherUserAvatar.setVisibility(View.GONE);
baseViewBinding.myAvatar.setVisibility(View.GONE);
baseViewBinding.myName.setVisibility(View.GONE);
baseViewBinding.messageStatus.setVisibility(View.GONE);
}
调整消息内容布局
若需要调整消息内容的布局,如消息内容居中显示,可以重写 ViewHolder的onLayoutConfig
方法。
Java@Override
protected void onLayoutConfig(ChatMessageBean messageBean) {
// 1. 获取messageContentGroup当前布局参数
ConstraintLayout.LayoutParams params = (ConstraintLayout.LayoutParams) baseViewBinding.messageContentGroup.getLayoutParams();
// 2. 清除原有约束
params.startToEnd = ConstraintLayout.LayoutParams.UNSET; // 清除与otherUserAvatar的关联
params.endToStart = ConstraintLayout.LayoutParams.UNSET; // 清除与myAvatar的关联
// 3. 设置新的约束使其充满父布局
params.startToStart = ConstraintLayout.LayoutParams.PARENT_ID; // 左边对齐父布局
params.endToEnd = ConstraintLayout.LayoutParams.PARENT_ID; // 右边对齐父布局
params.matchConstraintPercentWidth = 0.9f; // 设置宽度百分比为100%
params.matchConstraintDefaultWidth = ConstraintLayout.LayoutParams.MATCH_CONSTRAINT_PERCENT; // 宽度百分比适应内容
// 4. 应用新的布局参数
baseViewBinding.messageContentGroup.setLayoutParams(params);
// 1. 获取messageContentGroup当前布局参数
ConstraintLayout.LayoutParams messageParams = (ConstraintLayout.LayoutParams) baseViewBinding.messageContainer.getLayoutParams();
messageParams.matchConstraintPercentWidth = 1f; // 设置宽度百分比为100%
messageParams.matchConstraintDefaultWidth = ConstraintLayout.LayoutParams.MATCH_CONSTRAINT_PERCENT; // 宽度百分比适应内容
// 2. 应用新的布局参数
baseViewBinding.messageContainer.setLayoutParams(messageParams);
}
注册自定义 ViewHolder
将 CustomerSampleViewHolder
添加到 IM UIKit,使其在加载后能够处理您的自定义消息。
Java// 在 IM UIKit 初始化后注册
ChatKitClient.addCustomViewHolder(1002, CustomerSampleViewHolder.class);
接收消息
IM UIKit 中已实现消息接收逻辑,如果您需要接收消息实现自己其他的业务逻辑,只需注册消息监听器即可。
Javaprivate final NEChatListener messageListener =
new NEChatListener() {
// 接收到新消息
@Override
public void onReceiveMessages(@NonNull List<IMMessageInfo> messages) {
// 处理收到的消息
}
};
// 注册消息接收监听
ChatRepo.addMessageListener(messageListener);