逐条消息已读功能
IMKit 内置页面中已默认实现逐条消息已读功能。当接收端查看到某条消息时,会发送这条消息的已读回执,发送端则会收到这条消息的已读回执回调,同时刷新消息已读标记图标,例如绿色的对勾图标。
逐条消息已读回执发送逻辑:进入单群聊会话页面后,当某条接收的消息在屏幕中展示后,才会触发这条消息的已读回执的发送。
已读回执显示开关
逐条消息已读功能开通后,IMKit 客户端的回执显示功能默认开启,在单聊和群聊中默认会展示消息回执。
您可以将 res 下 rc_config.xml 中下面的变量设为 false 来关闭已读回执的显示。
<bool name="rc_read_receipt">false</bool>
上面变量配置为 false 后,单聊和群聊中的逐条已读回执显示都会被关闭。
您也可以在进入会话列表页面之前,通过下面的代码动态配置已读回执显示支持的会话类型。
// 下面的代码将逐条已读回执显示配置为仅在单聊中支持,群聊中将不显示逐条已读回执。
RongConfigCenter.conversationConfig().setSupportReadReceiptConversationType(Conversation.ConversationType.PRIVATE);
单聊已读回执
在单聊会话中,发送方会实时收到消息的已读状态更新。在 IMKit 内置页面中,单聊已读状态显示在两处:
-
会话列表页面:会话列表的每条会话会显示会话中的最后一条消息的预览。如果单聊会话最后一条消息是自己发送的消息,那么会展示已读回执状态的图标。
- 如果最后一条消息未被对方阅读,默认展示灰色的圆圈图标。
- 如果最后一条消息被对方阅读,默认展示绿色的对勾图标。
-
消息列表页面:在发送方的单聊会话页面,消息的左下角会显示对号,表示对方 已读,如果展示灰圈,则表示对方未读。


群聊已读回执
在群聊会话中,发送方会实时收到消息的已读状态更新。在 IMKit 内置页面中,群聊已读状态显示在消息列表页面,消息的左下角会显示消息已读状态。
消息阅读情况说明:
- 无人阅读时,显示灰色圆圈;
- 部分人阅读时,显示绿色饼状图,代表已读人数与总人数的占比情况;
- 所有人已读时,显示绿色对钩。
已读回执详情页面
点击消息左下角已读状态按钮,即可进入已读回执详情页面。单聊会话页面不可点击。
以下是已读回执详情页面相关组件的详细说明:
- MessageReadDetailActivity: 群组消息已读未读页面的容器类,负责加载并显示
MessageReadDetailFragment。 - MessageReadDetailFragment: 群组消息已读未读页面的核心部分,负责展示已读和未读用户列 表,并处理用户交互事件。
- MessageReadDetailViewModel: 数据和业务逻辑的处理类,负责从服务器获取消息的已读和未读用户数据,并将数据传递给
MessageReadDetailFragment。 - XML 布局:
rc_page_message_read_detail.xml
自定义已读回执按钮点击事件
可以设置会话界面操作的监听器,重写 onReadReceiptStateClick 方法来自定义点击事件,返回 true 表示由业务侧处理点击逻辑,SDK 后续逻辑不再执行。
IMCenter.setConversationClickListener(
new ConversationClickListener() {
@Override
public boolean onUserPortraitClick(
Context context,
Conversation.ConversationType conversationType,
UserInfo user,
String targetId) {
return false;
}
@Override
public boolean onUserPortraitLongClick(
Context context,
Conversation.ConversationType conversationType,
UserInfo user,
String targetId) {
return false;
}
@Override
public boolean onMessageClick(
Context context, View view, Message message) {
return false;
}
@Override
public boolean onMessageLongClick(
Context context, View view, Message message) {
return false;
}
@Override
public boolean onMessageLinkClick(
Context context, String link, Message message) {
return false;
}
@Override
public boolean onReadReceiptStateClick(
Context context, Message message) {
return false;
}
});
页面定制化
可以参照 用户托管页面设计 的自定义 Fragment 形式
// 自定义 Fragment(比如:CustomMessageReadDetailFragment)
public class CustomMessageReadDetailFragment extends MessageReadDetailFragment {
// 重写返回自定义的 ViewModel(比如:CustomMessageReadDetailViewModel)
@Override
protected MessageReadDetailViewModel onCreateViewModel(Bundle bundle) {
return new ViewModelProvider(this, new ViewModelFactory(bundle))
.get(CustomMessageReadDetailViewModel.class);
}
@Override
protected void onViewReady(@NonNull MessageReadDetailViewModel viewModel) {
super.onViewReady(viewModel);
// 更改标题内容
headComponent.setTitleText("新标题");
// 重写标题栏返回按钮点击事件
headComponent.setLeftClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// 自定义返回按钮的逻辑
}
});
// 重写标题栏右侧按钮点击事件(如果有)
headComponent.setRightClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// 自定义右侧按钮的逻辑
}
});
// 设置标题栏右侧按钮图标
headComponent.setRightTextDrawable(R.drawable.rc_right_icon);
}
}
public class CustomKitFragmentFactory extends KitFragmentFactory {
@NonNull
@Override
public MessageReadDetailFragment newMessageReadDetailFragment(@NonNull Bundle args) {
CustomMessageReadDetailFragment fragment = new CustomMessageReadDetailFragment();
fragment.setArguments(args);
return fragment;
}
}
// 设置自定义工厂,在 Application 中初始化 IMUIKit,并设置自定义的 Fragment 工厂
public class MyApp extends Application {
@Override
public void onCreate() {
super.onCreate();
// 设置自定义的 Fragment 工厂
IMCenter.setKitFragmentFactory(new CustomKitFragmentFactory());
}
}