跳到主要内容

会话页面

会话页面即应用程序中的聊天页面,主要由消息列表和输入区两部分组成。IMKit 提供默认的会话页面 Activity 类和基于 Fragment 类实现的会话页面。

  • 基于 Activity:IMKit SDK 提供了默认会话页面 RongConversationActivity。页面包含标题栏、消息列表和输入区域。在会话列表页点击某条会话时,会跳转到对应的会话页面。应用程序可以直接使用 RongConversationActivity 或通过继承创建自定义的会话 Activity。
  • 基于 Fragment:您可以在应用 Activity 中集成 IMKit 提供的会话 Fragment。

聊天界面

聊天界面一般由三个部分组成:标题栏、消息列表、输入区域。

提示

IMKit 在默认会话页面 Activity(RongConversationActivity)包含了标题栏的实现。如果基于 Fragment 构建会话页面,请自行实现标题栏。

conversation(width=250) conversation(width=250) conversation(width=250)

标题栏

IMKit 仅在默认的会话页面 RongConversationActivity 中实现了会话页面标题栏。标题栏用于显示会话的标题,该标题可以是群组名称,也可以是一对一聊天中另一个用户的名称。在单聊会话中,标题栏可显示对方的输入状态。标题栏的视图是在 TitleBar 中创建和控制的。

标题栏提供两个按钮,一个位于组件的左侧,另一个位于组件的右上角。当点击左按钮时,会调用 Activity 的 finish() 方法来退出当前屏幕。右侧菜单按钮默认不展示。在通过继承 RongConversationActivity 创建的子类中,您可以通过 mTitleBarsetRightVisible 方法展示右侧按钮,通过 setOnRightIconClickListener 设置监听器,在用户点击右侧按钮后跳转到您自行实现的页面或进行其他自定义操作。

如果您使用 ConversationFragment 构建自己的会话页面,则默认不包含标题栏。您可以参考 IMKit 的标题栏组件自行实现标题栏,详见 TitleBar.java

消息列表

消息列表组件按时间顺序显示所有消息的列表。当前用户发送的消息与其他成员发送的消息区分显示。消息列表的视图是在 BaseMessageItemProvider 和各类型消息的展示模板中创建和自定义的。您还可以使用 MessageListAdapter 自定义列表视图中的每个项目。

输入区域

消息输入组件是用户可以输入文本、文件、语音、图像、视频等消息的地方。输入区域的视图是在 RongExtension 中统一控制的。

用法

IMKit 提供了 Activity 和 Fragment 来创建会话页面。RongConversationActivity 是默认提供的会话页面,在会话列表页点击某条会话时,会跳转到对应的会话页面。您可以根据需要,选择直接使用默认的会话页面 Activity,继承 RongConversationActivity,或者使用 ConversationFragment 构建自定义会话 Activity。

启动会话页面

启动会话页面 Activity 有两种方式:通过调用 SDK 内置的 Activity 路由器启动,或通过 intent 跳转。您也可以自定义会话页启动方式,实现从应用的其它 Activity 启动会话页面。

提示

IMKit 中默认已实现了会话页跳转逻辑。默认情况下,点击会话列表页的会话项目后,SDK 将自动跳转到 RongConversationActivity,应用层无需处理。

使用 RouteUtils

RouteUtils 是 IMKit 内置的 Activity 路由器,封装了 SDK 内部各页面跳转方法,可避免应用程序进行重复的 intent 封装。

提示

如果您构建了自定义的会话 Activity,必须先向 RouteUtils 注册自定义 Activity,才能通过这种方式跳转到自定义会话 Activity,否则跳转的是 SDK 默认的 RongConversationActivity

跳转到会话 Activity:

String targetId = "userId";
ConversationIdentifier conversationIdentifier = new ConversationIdentifier(Conversation.ConversationType.PRIVATE, targetId);

RouteUtils.routeToConversationActivity(context, conversationIdentifier, false, bundle)
参数类型说明
contextContextActivity 上下文
conversationIdentifierConversationIdentifier会话类型
disableSystemEmojiBoolean是否隐藏 SDK 内置 Emoji 表情。true 为隐藏,false 为不隐藏。
bundleBundle扩展参数

通过 intent 跳转

您可以自己组装 Intent, 使用 Android 默认机制进行跳转。

Intent intent = new Intent(context, ConversationActivity.class);
intent.putExtra(RouteUtils.CONVERSATION_TYPE, type.getName().toLowerCase());
intent.putExtra(RouteUtils.TARGET_ID, targetId);
intent.putExtra(RouteUtils.DISABLE_SYSTEM_EMOJI, false);
intent.putExtras(bundle);
context.startActivity(intent);

继承默认会话页面 Activity

您可以通过继承 RongConversationActivity 创建自定义会话 Activity,实现对会话页面的调整。注意,必须向 RouteUtils 注册自定义的会话 Activity。注册之后,自定义的会话 Activity 将替换 IMKit 默认的会话 Activity。替换完成后,当在会话列表页点击会话时,SDK 会跳转到您注册的自定义会话 Activity。注册方法在应用生命周期内、主进程中调用一次即可。

RouteUtils.registerActivity(RouteUtils.RongActivityType.ConversationActivity, MyConversationActivity.class)

使用 Fragment 构建自定义会话 Activity

为方便应用程序自定义会话页面,推荐您继承使用会话 Fragment 类 ConversationFragment 构建自定义的会话 Activity。您需要将自定义会话 Activity 注册到 IMKit SDK 中,以替换 IMKit 默认的会话 Activity。

  1. 您可以在应用 Activity 中集成 IMKit 提供的会话 Fragment。以下示例声明一个新的 MyConversationActivity

    <activity
    android:name="xxx.xxx.MyConversationActivity"
    android:screenOrientation="portrait"
    android:windowSoftInputMode="stateHidden|adjustResize">
    </activity>
  2. 实现 Activity 布局。此处以 activity_conversation.xml 为例。

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <FrameLayout
    android:id="@+id/container"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />
    </LinearLayout>
  3. 通过继承 IMKit 的 ConversationFragment 创建子类,在 MyConversationActivityonCreate() 方法中使用您自定义的会话 Fragment 子类。

    class MyConversationActivity extends FragmentActivity  {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    super.setContentView(R.layout.activity_conversation);

    // 使用 ConversationFragment 的子类添加会话界面
    ConversationFragment conversationFragment = new AppConversationFragment();
    FragmentManager manager = getSupportFragmentManager();
    FragmentTransaction transaction = manager.beginTransaction();
    transaction.replace(R.id.container, conversationFragment);
    transaction.commit();
    }
    }
  4. RouteUtils 注册自定义的会话 Activity,以替换 IMKit 默认的会话 Activity。替换完成后,当在会话列表页点击会话时,SDK 会跳转到您注册的自定义会话 Activity。注册方法在应用生命周期内、主进程中调用一次即可。

    RouteUtils.registerActivity(RouteUtils.RongActivityType.ConversationActivity, MyConversationActivity.class)

定制化

您可以通过修改 IMKit 全局配置和重写 RongConversationActivityConversationFragment 的方法来自定义聊天页面。

在开始定制化之前,建议您首先继承 SDK 内置会话页面 RongConversationActivity 或继承使用 ConversationFragment,创建并实现自己的会话页面 Activity。

提示

会话页面中部分样式与行为受 IMKit 全局配置影响。如需了解全局配置,参见 [配置指南]。

修改用户头像形状与大小

会话页面的消息列表中显示的用户头像(指消息上显示的头像)可以通过 IMKit 全局配置修改。

头像形状默认为矩形,可修改为圆角显示。头像显示大小默认值为 40dp*40dp。请在 SDK 初始化之后调用以下代码进行设置:

   RongConfigCenter.featureConfig().setKitImageEngine(new GlideKitImageEngine() {
@Override
public void loadConversationPortrait(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView, Message message) {
Glide.with(context).load(url)
.apply(RequestOptions.bitmapTransform(new CircleCrop()))
.into(imageView);
}
});
提示

修改 IMKit 全局配置会影响 IMKit 中所有用户头像的显示。

隐藏用户昵称

IMKit 仅支持在单聊会话页面隐藏用户昵称。

// 设置是否显示用户昵称,仅支持单聊会话
RongConfigCenter.conversationConfig().setShowReceiverUserTitle(true);

隐藏默认 Emoji 表情

提示

SDK 从 5.2.3 开始支持禁用内置 Emoji。禁用后,表情面板不再显示 Emoji 标签页。

配置方式详见表情区域

设置默认拉取历史消息数

IMKit 在进入会话页面时和下拉页面时获取历史消息,默认拉取 10 条。优先从本地拉取,本地消息拉取完之后,如果已开通单群聊历史消息云存储功能,IMKit 还可从远端拉取历史消息。您可以修改默认拉取的历史消息数。

提示

拉取远端历史消息要求已开通单群聊历史消息云存储功能。

请在进入会话页面前设置。

// 默认拉取历史消息数量
RongConfigCenter.conversationConfig().setConversationHistoryMessageCount(10);
// 默认拉取远端历史消息数量
RongConfigCenter.conversationConfig().setConversationRemoteMessageCount(10);
提示

您可以自助开通单群聊历史消息云存储功能,详见开通单群聊消息云存储服务

修改长按消息菜单中的删除行为

IMKit 会话页面默认已在长按消息弹出的菜单中实现了删除消息的选项。

alt(width=250)

  • 如果 IMKit 版本 ≧ 5.6.3,默认实现的删除功能会删除本地消息,如果 App Key 已开通单群聊消息云端存储服务,则同步删除远端消息。
  • 如果 IMKit 版本 < 5.6.3,默认实现的删除功能仅删除本地消息,如果 App Key 已开通单群聊消息云端存储服务,不会删除服务端历史消息记录中的该条消息。用户再次获取历史消息、或触发离线消息补偿(卸载重装、换设备登录)时,该消息可能会再次出现在聊天页面中。如需删除远端消息,应用程序可修改删除按钮的默认行为。

如需修改 IMKit 会话页面中删除消息选项的默认行为,方法如下:

  • 如果 SDK 版本 ≧ 5.2.3,可通过 IMKit 全局配置修改 needDeleteRemoteMessage 属性。true 表示需要 IMKit 同步删除本地与远端消息。false 表示仅从本地消息数据库中删除消息。

    RongConfigCenter.conversationConfig().setNeedDeleteRemoteMessage(true);
  • 如果 5.1.3.19 ≦ SDK 版本 < 5.2.3,您需要自定义长按消息弹窗菜单,并添加自定义的删除操作。在实现自定义删除消息时调用 IMCenterdeleteRemoteMessages 方法,该方法可同时删除本地与远端消息,并刷新 UI。详见自定义长按消息菜单选项

提示

如果已有实现无法满足您的需求,可以直接使用 IMKit 核心类 IMCenter 提供的 API。具体的核心类、API 与 使用方法,详见删除消息

修改多选消息数量限制

IMKit 会话页面默认实现消息多选能力,在 IMKit 会话页面的消息列表中长按单条消息后,SDK 会弹出菜单,其中包含一个可进入下级菜单的「更多」选项,点击后会进入消息选择界面。

multi-01-v5(width=250) multi-01-v5(width=250)

IMKit 默认最多选择 100 条消息进行后续操作。您可以通过全局配置修改多选消息数量上限:

RongConfigCenter.conversationConfig().rc_max_message_selected_count = 100;

如果修改 IMKit 默认配置,您可以在应用 res/values 目录下创建 rc_config.xml 文件,修改以下配置项的值。

<integer name="rc_max_message_selected_count">100</integer>

隐藏长按消息弹窗中的更多按钮

在 IMKit 会话页面的消息列表中长按单条消息后,SDK 会弹出菜单,包含默认实现和展示的功能选项,例如「删除消息」、「引用消息」等,以及一个可进入下级菜单的「更多」选项。IMKit 支持通过修改全局配置隐藏弹窗中的「更多」选项。

multi-01-v5(height=500)

请在进入会话页面前设置。

RongConfigCenter.conversationConfig().setShowMoreClickAction(true);
提示

如果需要自定义菜单选项的显示名称、顺序、以及自行增删菜单选项,请参见自定义长按消息菜单选项

是否展示网络连接状态提示

当连接断开或者重连时,SDK 会在会话列表页面顶部展示连接状态提示栏。

(width=250)

您可以通过全局配置,在会话页面上禁用该提示:

RongConfigCenter.conversationConfig().rc_is_show_warning_notification = false;

如果修改 IMKit 默认配置,您可以在应用 res/values 目录下创建 rc_config.xml 文件,将以下变量的值设为 false 来关闭提示栏。该 XML 配置项会同时禁用会话页面与会话列表页面的连接状态提示栏。

<bool name="rc_is_show_warning_notification">false</bool>

是否清除通知栏通知

IMKit 支持在打开者会话页面与会话列表页面时,清除通知面板的所有通知。IMKit 中此开关默认关闭,即不清除通知。

您可以通过全局配置,设置在打开会话页面时清除所有通知:

RongConfigCenter.featureConfig().rc_wipe_out_notification_message = true;

如果修改 IMKit 默认配置,您可以在应用 res/values 目录下创建 rc_config.xml 文件,将以下变量的值设为 true。该 XML 配置项会同时影响会话页面与会话列表页面的默认行为。

<!--进入会话或会话列表界面,是否清除通知栏通知-->
<bool name="rc_wipe_out_notification_message">true</bool>

添加自定义头、尾、空布局

提示

IMKit 从 5.1.0 版本开始支持该功能。

IMKit 的 ConversationFragment 支持在消息列表中添加自定义的头(Header)、尾(Footer)和空(Empty)视图。

  1. 继承 IMKit 的 ConversationFragment 创建子类。

  2. 在子类中实现 addHeaderView()addFooterView()setEmptyView() 等方法,

  3. 在子类的 onViewCreated() 方法中按需调用自身的 addHeaderVew()addFooterView()setEmptyView() 等方法。

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);
    addHeaderView(view);
    addFooterView(view);
    setEmptyView(view);
    }
    /**
    * @param view 自定义列表 header view
    */
    public void addHeaderView(View view) {
    mAdapter.addHeaderView(view);
    }

    /**
    * @param view 自定义列表 footer view
    */
    public void addFooterView(View view) {
    mAdapter.addFootView(view);
    }

    /**
    * @param view 自定义列表 空数据 view
    */
    public void setEmptyView(View view) {
    mAdapter.setEmptyView(view);
    }

    /**
    * @param emptyId 自定义列表 空数据的 LayoutId
    */
    public void setEmptyView(@LayoutRes int emptyId) {
    mAdapter.setEmptyView(emptyId);
    }

其他定制化

您可以在以下文档中继续了解如何自定义会话页面:

提示

您可以直接参考 IMKit 源码中的 RongConversationActivity.javaConversationFragment.java 了解更多属性和方法。