# easemob-uikit-android
**Repository Path**: easemob-code/easemob-uikit-android
## Basic Information
- **Project Name**: easemob-uikit-android
- **Description**: 基于环信chat SDK 实现的UIKit,支持单群聊场景。
- **Primary Language**: Unknown
- **License**: Not specified
- **Default Branch**: main
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 0
- **Created**: 2025-11-05
- **Last Updated**: 2025-11-06
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# 单群聊 UIKit
_[English](README.md) | 中文_
单群聊 UIKit,是基于环信 IM SDK 的一款 UI 组件库,它提供了一些通用的 UI 组件,例如‘会话列表’、‘聊天界面’和‘联系人列表’等,开发者可根据实际业务需求通过该组件库快速地搭建自定义 IM 应用。单群聊 UIKit 中的组件在实现 UI 功能的同时,调用 IM SDK 相应的接口实现 IM 相关逻辑和数据的处理,因而开发者在 UIKit 时只需关注自身业务或个性化扩展即可。
本指南提供了 chat_uikit 框架在Android开发中的概述和使用示例,并介绍了此 UIKit 的各种组件和功能,让开发人员很好地了解 UIKit 的工作原理以及如何有效地使用它。
## 目录
- [单群聊 UIKit](#单群聊-uikit)
- [目录](#目录)
- [产品体验](#产品体验)
- [开发环境](#开发环境)
- [集成安装](#集成安装)
- [Gradle 接入集成](#gradle-接入集成)
- [Gradle 7.0 之前](#gradle-70-之前)
- [Gradle 7.0 之后](#gradle-70-之后)
- [Module 远程依赖](#module-远程依赖)
- [Module 源码集成](#module-源码集成)
- [防止代码混淆](#防止代码混淆)
- [UIKit 基本项目结构](#uikit-基本项目结构)
- [权限要求](#权限要求)
- [初始化及登录单群聊 UIKit](#初始化及登录单群聊-uikit)
- [初始化](#初始化)
- [登录](#登录)
- [退出登录](#退出登录)
- [快速搭建](#快速搭建)
- [快速创建聊天页面](#快速创建聊天页面)
- [使用 UIKitChatActivity](#使用-UIKitChatActivity)
- [使用 UIKitChatFragment](#使用-UIKitChatFragment)
- [快速创建会话列表页面](#快速创建会话列表页面)
- [快速创建联系人列表页面](#快速创建联系人列表页面)
- [高级定制](#高级定制)
- [聊天页面相关](#聊天页面相关)
- [通过 UIKitChatFragment.Builder 自定义设置](#通过-UIKitChatFragmentbuilder-自定义设置)
- [添加自定义消息布局](#添加自定义消息布局)
- [通过继承 UIKitChatFragment 进行自定义设置](#通过继承-UIKitChatFragment-进行自定义设置)
- [会话列表页面相关](#会话列表页面相关)
- [通过 ChatUIKitConversationListFragment.Builder 自定义设置](#通过-ChatUIKitConversationListFragmentbuilder-自定义设置)
- [添加自定义会话布局](#添加自定义会话布局)
- [通过继承 ChatUIKitConversationListFragment 进行自定义设置](#通过继承-ChatUIKitConversationListFragment-进行自定义设置)
- [联系人列表页面相关](#联系人列表页面相关)
- [通过 ChatUIKitContactsListFragment.Builder 自定义设置](#通过-ChatUIKitContactsListFragmentbuilder-自定义设置)
- [添加自定义联系人布局](#添加自定义联系人布局)
- [UIKit 提供的全局配置](#uikit-提供的全局配置)
- [UIKit 用户信息相关](#uikit-用户信息相关)
- [当前登录用户信息](#当前登录用户信息)
- [联系人信息提供](#联系人信息提供)
- [群组成员信息提供](#群组成员信息提供)
- [UIKit 信息处理逻辑](#uikit-信息处理逻辑)
- [更新 UIKit 缓存信息](#更新-uikit-缓存信息)
- [UIKit 对明暗主题的支持](#uikit-对明暗主题的支持)
## 产品体验
在这个项目中,“app”文件夹中有一个最佳实践演示项目,供您构建自己的业务能力。
如果你想体验 chat_uikit 的功能,你可以扫描以下二维码来尝试演示。

## 开发环境
- Android Studio Flamingo | 2022.2.1 及以上
- Gradle 8.0 及以上
- targetVersion 26 及以上
- Android SDK API 21 及以上
- JDK 17 及以上
## 集成安装
单群聊 UIKit 支持 Gradle 接入和 Module 源码集成。
### Gradle 接入集成
#### Gradle 7.0 之前
在项目根目录的 build.gradle 或者 build.gradle.kts 文件中添加 MavenCentral 远程仓库。
```kotlin
buildscript {
repositories {
...
mavenCentral()
}
}
allprojects {
repositories {
...
mavenCentral()
}
}
```
#### Gradle 7.0 之后
在项目根目录的 `settings.gradle` 或者 `settings.gradle.kts` 文件中检查并添加 MavenCentral 远程仓库。
```kotlin
pluginManagement {
repositories {
...
mavenCentral()
}
}
dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositories {
...
mavenCentral()
}
}
```
### Module 远程依赖
在 app 项目 build.gradle.kts 中添加以下依赖,其中 `x.y.z` 表示[最新版本号](https://central.sonatype.com/artifact/io.hyphenate/ease-chat-kit/versions):
```kotlin
implementation("io.hyphenate:ease-chat-kit:x.y.z")
```
### Module 源码集成
从 github 获取 [Chat UIKit](https://github.com/easemob/easemob-uikit-android) 源码,按照下面的方式集成:
1. 在根目录 settings.gradle.kts 文件(/Gradle Scripts/settings.gradle.kts(Project Settings))中添加如下代码:
```kotlin
include(":ease-chat-kit")
project(":ease-chat-kit").projectDir = File("../easemob-uikit-android/ease-im-kit")
```
2. 在 `build.gradle.kts` 文件 app/build.gradle(Module: app)中添加如下代码:
```kotlin
//chatuikit-android
implementation(project(mapOf("path" to ":ease-chat-kit")))
```
### 防止代码混淆
在 `app/proguard-rules.pro` 文件中添加如下行,防止代码混淆:
```kotlin
-keep class com.hyphenate.** {*;}
-dontwarn com.hyphenate.**
```
## UIKit 基本项目结构
```
└── uikit
├── ChatUIKitClient // UIKit SDK 入口
├── ChatUIKitConfig // UIKit SDK 配置类
├── feature // UIKit 功能模块
│ ├── chat // 聊天功能模块
│ │ ├── activities // 聊天功能模块的 Activity 文件夹
│ │ │ └── UIKitChatActivity // UIKit内置的聊天界面
│ │ ├── adapter // 聊天功能模块的适配器文件夹
│ │ │ └── ChatUIKitMessagesAdapter // 聊天功能模块的消息列表适配器
│ │ ├── reply // 聊天功能模块的回复功能相关
│ │ ├── report // 聊天功能模块的举报消息功能相关
│ │ ├── chathistory // 聊天功能模块的消息历史功能相关
│ │ ├── forward // 聊天功能模块的消息转发功能相关
│ │ ├── reaction // 聊天功能模块的消息 Reaction 功能相关
│ │ ├── search // 聊天功能模块的搜索消息功能相关
│ │ ├── translation // 聊天功能模块的消息翻译功能相关
│ │ ├── viewholders // 聊天功能模块的消息类型 ViewHolder
│ │ ├── widgets // 聊天功能模块的自定义 View
│ │ └── UIKitChatFragment // UIKit内提供的聊天 Fragment
│ ├── conversation // 会话列表功能模块
│ │ ├── adapter // 会话列表功能模块的适配器文件夹
│ │ │ └── ChatUIKitConversationListAdapter // 会话列表功能模块的会话列表适配器
│ │ ├── viewholders // 会话列表功能模块的会话类型 ViewHolder
│ │ ├── widgets // 会话列表功能模块的自定义 View
│ │ └── ChatUIKitConversationListFragment // UIKit内提供的会话列表 Fragment
│ ├── thread // 子区功能模块
│ │ ├── adapter // 子区功能模块的适配器文件夹
│ │ │ └── ChatUIKitThreadListAdapter // 子区功能模块的子区列表适配器
│ │ ├── viewholder // 子区列表功能模块的子区列表类型 ViewHolder
│ │ ├── widgets // 子区列表功能模块的自定义 View
│ │ └── ChatUIKitThreadActivity // UIKit内提供的子区聊天页面
│ ├── contact // 联系人列表功能模块
│ │ ├── adapter // 联系人列表功能模块的适配器文件夹
│ │ │ └── ChatUIKitContactListAdapter // 联系人列表功能模块的联系人列表适配器
│ │ ├── viewholders // 联系人列表功能模块的相关 ViewHolder
│ │ ├── widgets // 联系人列表功能模块的自定义 View
│ │ └── ChatUIKitContactsListFragment // UIKit内提供的联系人列表 Fragment
│ └── group // 群组功能模块
├── repository // UIKit SDK 数据仓库
├── viewmodel // UIKit SDK ViewModel
├── provider // UIKit SDK Provider
├── common // UIKit SDK 公共类
├── interfaces // UIKit SDK 接口类
└── widget // UIKit SDK 自定义 View
```
## 权限要求
```xml
```
## 初始化及登录单群聊 UIKit
### 初始化
使用单群聊 UIKit 需要进行初始化,示例代码如下:
```kotlin
val options = ChatOptions()
options.appKey = "[Your appkey]"
ChatUIKitClient.init(this, options)
```
### 登录
```kotlin
val user = ChatUIKitProfile(userName, nickname, avatarUrl)
ChatUIKitClient.login(user, token
, onSuccess = {
// Add success logic
}, onError = { code, error ->
// Add error logic
}
)
```
### 退出登录
```kotlin
ChatUIKitClient.logout(unbindDeviceToken
, onSuccess = {
// Add success logic
}, onError = { code, error ->
// Add error logic
}
)
```
## 快速搭建
### 快速创建聊天页面
#### 使用 UIKitChatActivity
单群聊 UIKit 提供了 UIKitChatActivity 页面,调用 UIKitChatActivity#actionStart 方法即可,示例代码如下:
```kotlin
// conversationId: 1v1 is peer's userID, group chat is groupID
// chatType can be ChatUIKitType#SINGLE_CHAT, ChatUIKitType#GROUP_CHAT
UIKitChatActivity.actionStart(mContext, conversationId, chatType)
```
UIKitChatActivity 页面主要进行了权限的请求,比如相机权限,语音权限等。
#### 使用 UIKitChatFragment
开发者也可以使用 UIKit 提供的 UIKitChatFragment 创建聊天页面,示例代码如下:
```kotlin
class ChatActivity: AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_chat)
// conversationID: 1v1 is peer's userID, group chat is groupID
// chatType can be ChatUIKitType#SINGLE_CHAT, ChatUIKitType#GROUP_CHAT
UIKitChatFragment.Builder(conversationId, chatType)
.build()?.let { fragment ->
supportFragmentManager.beginTransaction()
.replace(R.id.fl_fragment, fragment).commit()
}
}
}
```
### 快速创建会话列表页面
UIKit 提供了 `ChatUIKitConversationListFragment` ,添加到 Activity 中即可使用。
示例如下:
```kotlin
class ConversationListActivity: AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_conversation_list)
ChatUIKitConversationListFragment.Builder()
.build()?.let { fragment ->
supportFragmentManager.beginTransaction()
.replace(R.id.fl_fragment, fragment).commit()
}
}
}
```
### 快速创建联系人列表页面
UIKit 提供了 ChatUIKitContactsListFragment ,添加到 Activity 中即可使用。
示例如下:
```kotlin
class ContactListActivity: AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_contact_list)
ChatUIKitContactsListFragment.Builder()
.build()?.let { fragment ->
supportFragmentManager.beginTransaction()
.replace(R.id.fl_fragment, fragment).commit()
}
}
}
```
## 高级定制
### 聊天页面相关
#### 通过 UIKitChatFragment.Builder 自定义设置
UIKitChatFragment 提供了 Builder 构建方式,方便开发者进行一些自定义设置,目前提供的设置项如下:
```kotlin
// conversationID: 1v1 is peer's userID, group chat is groupID
// chatType: SINGLE_CHAT, GROUP_CHAT, CHATROOM
UIKitChatFragment.Builder(conversationID, chatType)
.useTitleBar(true)
.setTitleBarTitle("title")
.setTitleBarSubTitle("subtitle")
.enableTitleBarPressBack(true)
.setTitleBarBackPressListener(onBackPressListener)
.setSearchMessageId(searchMessageId)
.getHistoryMessageFromServerOrLocal(false)
.setOnChatExtendMenuItemClickListener(onChatExtendMenuItemClickListener)
.setOnChatInputChangeListener(onChatInputChangeListener)
.setOnMessageItemClickListener(onMessageItemClickListener)
.setOnMessageSendCallback(onMessageSendCallback)
.setOnWillSendMessageListener(willSendMessageListener)
.setOnChatRecordTouchListener(onChatRecordTouchListener)
.setOnMessageForwardCallback(onMessageForwardCallback)
.setOnSendCombineMessageCallback(onSendCombineMessageCallback)
.setOnReactionMessageListener(onReactionMessageListener)
.setOnModifyMessageListener(onModifyMessageListener)
.setOnReportMessageListener(onReportMessageListener)
.setOnTranslationMessageListener(onTranslationMessageListener)
.setMsgTimeTextColor(msgTimeTextColor)
.setMsgTimeTextSize(msgTimeTextSize)
.setReceivedMsgBubbleBackground(receivedMsgBubbleBackground)
.setSentBubbleBackground(sentBubbleBackground)
.showNickname(false)
.hideReceiverAvatar(false)
.hideSenderAvatar(true)
.setChatBackground(chatBackground)
.setChatInputMenuBackground(inputMenuBackground)
.setChatInputMenuHint(inputMenuHint)
.sendMessageByOriginalImage(true)
.setThreadMessage(isChatThread)
.setTargetTranslationList(targetTranslationList)
.setEmptyLayout(R.layout.layout_chat_empty)
.setCustomAdapter(customAdapter)
.setCustomFragment(myChatFragment)
.build()
```
`UIKitChatFragment#Builder` 提供的方法解释:
| 方法 | 说明 |
| -------------------------------------- | ---------------------------------------------------- |
| useTitleBar() | 是否使用默认的标题栏(ChatUIKitTitleBar)。
- true:是。
- (默认) false: 否。 |
| setTitleBarTitle() | 设置标题栏的标题。 |
| setTitleBarSubTitle() | 设置标题栏的子标题。 |
| enableTitleBarPressBack() | 设置是否支持显示返回按钮。
- true:是。
- (默认) false: 否。 |
| setTitleBarBackPressListener() | 设置点击标题栏返回按钮的监听事件。 |
| setSearchMessageId() | 设置搜索消息 ID,聊天将标识为 ChatUIKitLoadDataType.SEARCH |
| getHistoryMessageFromServerOrLocal() | 设置优先从服务器还是本地获取消息。 |
| setOnChatExtendMenuItemClickListener() | 设置扩展功能的条目点击事件监听。 |
| setOnChatInputChangeListener() | 设置菜单中文本变化的监听。 |
| setOnMessageItemClickListener() | 设置消息条目的点击事件监听,包括气泡区域及头像的点击及长按事件。 |
| setOnMessageSendCallback() | 设置发送消息的结果回调监听。 |
| setOnWillSendMessageListener() | 设置发送消息前添加消息扩展属性的回调。 |
| setOnChatRecordTouchListener() | 设置录音按钮的触摸事件回调。 |
| setOnMessageForwardCallback() | 设置消息转发的结果回调。 |
| setOnSendCombineMessageCallback() | 设置合并消息发送的结果回调。 |
| setOnReactionMessageListener() | 设置操作消息 Reaction 的结果回调。 |
| setOnModifyMessageListener() | 设置编辑消息的结果回调监听。 |
| setOnReportMessageListener() | 设置举报消息的结果回调监听。 |
| setOnTranslationMessageListener() | 设置消息翻译的结果回调监听。 |
| setMsgTimeTextColor() | 设置时间线文本的颜色。 |
| setMsgTimeTextSize() | 设置时间线文本的字体大小。 |
| setReceivedMsgBubbleBackground() | 设置接收消息气泡区域的背景。 |
| setSentBubbleBackground() | 设置发送消息气泡区域的背景。 |
| showNickname() | 是否显示昵称。
- true:是。
- (默认) false: 否。 |
| hideReceiverAvatar() | 设置不展示接收方头像,默认展示接收方头像。 |
| hideSenderAvatar() | 设置不展示发送方头像,默认展示发送方头像。 |
| setChatBackground() | 设置聊天列表区域的背景。 |
| setChatInputMenuBackground() | 设置菜单区域的背景。 |
| setChatInputMenuHint() | 设置菜单区域输入文本框的提示文字。 |
| sendMessageByOriginalImage() | 设置图片消息是否发送原图。
- true:是。
- (默认) false: 否。 |
| setThreadMessage() | 设置当前会话是否是子区会话。
- true:是。
- (默认) false: 否。 |
| setTargetTranslationList() | 设置翻译目标语言列表。需要开通消息翻译功能。 |
| setEmptyLayout() | 设置聊天列表的空白页面。 |
| setCustomAdapter() | 设置自定义的适配器,默认为 ChatUIKitMessagesAdapter。 |
| setCustomFragment() | 设置自定义聊天 Fragment,需要继承自 UIKitChatFragment。 |
#### 添加自定义消息布局
开发者可以继承 ChatUIKitMessagesAdapter , ChatUIKitRowViewHolder 和 ChatUIKitRow 实现自己的 CustomMessageAdapter ,CustomChatTypeViewViewHolder 和 CustomTypeChatRow ,然后将 CustomMessageAdapter 设置到 UIKitChatFragment#Builder#setCustomAdapter 中。
(1)创建自定义适配器 CustomMessageAdapter 继承自 ChatUIKitMessagesAdapter,重写 getViewHolder 和 getItemNotEmptyViewType 方法。
```kotlin
class CustomMessageAdapter: ChatUIKitMessagesAdapter() {
override fun getItemNotEmptyViewType(position: Int): Int {
// 根据消息类型设置自己的 itemViewType。
// 如果要使用默认的,返回 super.getItemNotEmptyViewType(position) 即可。
return CUSTOM_YOUR_MESSAGE_TYPE
}
override fun getViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
// 根据返回的 viewType 返回对应的 ViewHolder。
// 返回自定义的 ViewHolder 或者 使用默认的 super.getViewHolder(parent, viewType)
return CUSTOM_VIEW_HOLDER()
}
}
```
(2)创建 CustomTypeChatRow ,继承自 ChatUIKitRow。
```kotlin
class CustomTypeChatRow(
private val context: Context,
private val attrs: AttributeSet? = null,
private val defStyle: Int = 0,
isSender: Boolean = false
): ChatUIKitRow(context, attrs, defStyle, isSender) {
override fun onInflateView() {
inflater.inflate(if (!isSender) R.layout.layout_row_received_custom_type
else R.layout.layout_row_sent_custom_type,
this)
}
override fun onSetUpView() {
(message?.getMessage()?.body as? ChatTextMessageBody)?.let { txtBody ->
contentView.text = txtBody.message
}
}
}
```
(3)创建 CustomChatTypeViewViewHolder ,继承自 ChatUIKitRowViewHolder。
```kotlin
class CustomChatTypeViewViewHolder(
itemView: View
): ChatUIKitRowViewHolder(itemView) {
override fun onBubbleClick(message: ChatMessage?) {
super.onBubbleClick(message)
// Add click event
}
}
```
(4)完善 CustomMessageAdapter。
```kotlin
class CustomMessageAdapter: ChatUIKitMessagesAdapter() {
override fun getItemNotEmptyViewType(position: Int): Int {
// 根据消息类型设置自己的 itemViewType。
mData?.get(position)?.getMessage()?.let { msg ->
msg.getStringAttribute("type", null)?.let { type ->
if (type == CUSTOM_TYPE) {
return if (msg.direct() == ChatMessageDirection.SEND) {
VIEW_TYPE_MESSAGE_CUSTOM_VIEW_ME
} else {
VIEW_TYPE_MESSAGE_CUSTOM_VIEW_OTHER
}
}
}
}
// 如果要使用默认的,返回 super.getItemNotEmptyViewType(position) 即可。
return super.getItemNotEmptyViewType(position)
}
override fun getViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
// 根据返回的 viewType 返回对应的 ViewHolder。
if (viewType == VIEW_TYPE_MESSAGE_CUSTOM_VIEW_ME || viewType == VIEW_TYPE_MESSAGE_CUSTOM_VIEW_OTHER) {
CustomChatTypeViewViewHolder(
CustomTypeChatRow(parent.context, isSender = viewType == VIEW_TYPE_MESSAGE_CUSTOM_VIEW_ME)
)
}
// 返回自定义的 ViewHolder 或者 使用默认的 super.getViewHolder(parent, viewType)
return super.getViewHolder(parent, viewType)
}
companion object {
private const val CUSTOM_TYPE = "custom_type"
private const val VIEW_TYPE_MESSAGE_CUSTOM_VIEW_ME = 1000
private const val VIEW_TYPE_MESSAGE_CUSTOM_VIEW_OTHER = 1001
}
}
```
(5)添加 CustomMessageAdapter 到 UIKitChatFragment#Builder。
```kotlin
builder.setCustomAdapter(CustomMessageAdapter())
```
#### 通过继承 UIKitChatFragment 进行自定义设置
创建自定义 CustomChatFragment,继承自 UIKitChatFragment,并设置到 UIKitChatFragment#Builder 中。
```kotlin
builder.setCustomFragment(customChatFragment)
```
(1)列表控件相关功能设置
获取 `ChatUIKitMessageListLayout` 对象:
```kotlin
val chatMessageListLayout:ChatUIKitMessageListLayout? = binding?.layoutChat?.chatMessageListLayout
```
ChatUIKitMessageListLayout 提供了如下方法:
| 方法 | 说明 |
| ------------------------------ | ---------------------------------------------------- |
| setViewModel() | UIKit 中提供了默认的实现 ChatUIKitMessageListViewModel,开发者可以继承 IChatMessageListRequest 添加自己的数据逻辑。 |
| setMessagesAdapter() | 设置消息列表的适配器,需要是 ChatUIKitMessagesAdapter 的子类。 |
| getMessagesAdapter() | 返回消息列表的适配器。 |
| addHeaderAdapter() | 添加消息列表的头布局的适配器。 |
| addFooterAdapter() | 添加消息列表的尾布局的适配器。 |
| removeAdapter() | 移除指定适配器。 |
| addItemDecoration() | 添加消息列表的装饰器。 |
| removeItemDecoration() | 移除消息列表的装饰器。 |
| setAvatarDefaultSrc() | 设置条目的默认头像。 |
| setAvatarShapeType() | 设置头像的样式,分为默认样式,圆形和矩形三种样式。 |
| showNickname() | 是否展示条目的昵称,UIKitChatFragment#Builder 也提供了此功能的设置方法。 |
| setItemSenderBackground() | 设置发送方的背景,UIKitChatFragment#Builder 也提供了此功能的设置方法。 |
| setItemReceiverBackground() | 设置接收方的背景,UIKitChatFragment#Builder 也提供了此功能的设置方法。 |
| setItemTextSize() | 设置文本消息的字体大小。 |
| setItemTextColor() | 设置文本消息的字体颜色。 |
| setTimeTextSize() | 设置时间线文本的字体大小,UIKitChatFragment#Builder 也提供了此功能的设置方法。 |
| setTimeTextColor() | 设置时间线文本的颜色,UIKitChatFragment#Builder 也提供了此功能的设置方法。 |
| setTimeBackground() | 设置时间线的背景。 |
| hideChatReceiveAvatar() | 不展示接收方头像,默认为展示,UIKitChatFragment#Builder 也提供了此功能的设置方法。 |
| hideChatSendAvatar() | 不展示发送方头像,默认为展示,UIKitChatFragment#Builder 也提供了此功能的设置方法。 |
| setOnChatErrorListener() | 设置发送消息时的错误回调,UIKitChatFragment#Builder 也提供了此功能的设置方法。 |
(2)扩展功能设置
```kotlin
val chatExtendMenu: IChatExtendMenu? = binding?.layoutChat?.chatInputMenu?.chatExtendMenu
```
拿到 chatExtendMenu 对象后,可以对于扩展功能可以进行添加,移除,排序以及处理扩展功能的点击事件等。
IChatExtendMenu 提供的方法解释:
| 方法 | 说明 |
| -------------------------------------- | ---------------------------------------------------- |
| clear() | 清除所有的扩展菜单项 |
| setMenuOrder() | 对指定的菜单项进行排序 |
| registerMenuItem() | 添加新的菜单项 |
- 监听扩展条目点击事件
开发者可以 UIKitChatFragment#Builder#setOnChatExtendMenuItemClickListener 进行监听,也可以在自定义的 Fragment 中 重写 onChatExtendMenuItemClick 方法。
```kotlin
override fun onChatExtendMenuItemClick(view: View?, itemId: Int): Boolean {
if(itemId == CUSTOM_YOUR_EXTEND_MENU_ID) {
// 处理你自己的点击事件逻辑
// 如果要消费点击事件需要返回 true
return true
}
return super.onChatExtendMenuItemClick(view, itemId)
}
```
(3)长按菜单功能设置
- 增加自定义菜单条目
```kotlin
binding?.let {
it.layoutChat.addItemMenu(menuId, menuOrder, menuTile)
}
```
ChatUIKitLayout 提供的长按菜单方法
| 方法 | 说明 |
| -------------------------------------- | ---------------------------------------------------- |
| clearMenu() | 清除菜单项。 |
| addItemMenu() | 添加新的菜单项。 |
| findItemVisible() | 通过指定 itemId 设置菜单项的可见性。 |
| setOnMenuChangeListener() | 设置菜单项的点击事件监听,UIKitChatFragment 中已经设置此监听。 |
- 处理菜单的事件
在自定义的 Fragment 中重写以下方法:
```kotlin
override fun onPreMenu(helper: ChatUIKitChatMenuHelper?, message: ChatMessage?) {
// 菜单展示前的回调事件,可以通过 helper 对象在这里设置菜单条目是否展示。
}
override fun onMenuItemClick(item: ChatUIKitMenuItem?, message: ChatMessage?): Boolean {
// 如果要拦截某个点击事件,需要设置返回 true。
return false
}
override fun onDismiss() {
// 可以在这里处理快捷菜单的隐藏事件。
}
```
(4)设置输入菜单相关属性
- 获取 ChatUIKitInputMenu 对象
```kotlin
val chatInputMenu: ChatUIKitInputMenu? = binding?.layoutChat?.chatInputMenu
```
ChatUIKitInputMenu 提供了如下方法:
| 方法 | 说明 |
| -------------------------- | ------------------------------------------------------------ |
| setCustomPrimaryMenu() | 设置自定义的菜单项,支持 View 和 Fragment 两种方式 |
| setCustomEmojiconMenu() | 设置自定义的表情功能,支持 View 和 Fragment 两种方式 |
| setCustomExtendMenu() | 设置自定义的扩展功能,支持 View ,Dialog 和 Fragment 三种方式 |
| setCustomTopExtendMenu() | 设置自定义的菜单顶部布局,支持 View ,Fragment 两种方式 |
| hideExtendContainer() | 隐藏扩展区域,包括表情区域和扩展功能区域 |
| hideInputMenu() | 隐藏除了菜单顶部区域外的区域 |
| showEmojiconMenu() | 展示表情功能区域 |
| showExtendMenu() | 展示扩展功能区域 |
| showTopExtendMenu() | 展示顶部扩展功能区域 |
| setChatInputMenuListener() | 设置输入菜单监听 |
| chatPrimaryMenu | 获取菜单项接口 |
| chatEmojiMenu | 获取表情功能菜单接口 |
| chatExtendMenu | 获取扩展功能接口 |
| chatTopExtendMenu | 获取顶部扩展功能接口 |
- 获取菜单项对象
```kotlin
val primaryMenu: IChatPrimaryMenu? = binding?.layoutChat?.chatInputMenu?.chatPrimaryMenu
```
IChatPrimaryMenu 提供了如下方法:
| 方法 | 说明 |
| ------------------- | ----------------------------------------- |
| onTextInsert() | 在光标处插入文本 |
| editText | 获取菜单输入框对象 |
| setMenuBackground() | 设置菜单的背景 |
- 获取表情菜单对象
```kotlin
val emojiconMenu: IChatEmojiconMenu? = binding?.layoutChat?.chatInputMenu?.chatEmojiMenu
```
IChatEmojiconMenu 提供了如下方法:
| 方法 | 说明 |
| --------------------- | ------------------ |
| addEmojiconGroup() | 添加自定义表情 |
| removeEmojiconGroup() | 移除指定的表情组 |
| setTabBarVisibility() | 设置 TabBar 可见性 |
添加自定义表情
```kotlin
binding?.let {
it.layoutChat.chatInputMenu?.chatEmojiMenu?.addEmojiconGroup(EmojiconExampleGroupData.getData())
}
```
### 会话列表页面相关
#### 通过 ChatUIKitConversationListFragment.Builder 自定义设置
ChatUIKitConversationListFragment 提供了 Builder 构建方式,方便开发者进行一些自定义设置,目前提供的设置项如下:
```kotlin
ChatUIKitConversationListFragment.Builder()
.useTitleBar(true)
.setTitleBarTitle("title")
.enableTitleBarPressBack(true)
.setTitleBarBackPressListener(onBackPressListener)
.useSearchBar(false)
.setItemClickListener(onItemClickListener)
.setOnItemLongClickListener(onItemLongClickListener)
.setOnMenuItemClickListener(onMenuItemClickListener)
.setConversationChangeListener(conversationChangeListener)
.setEmptyLayout(R.layout.layout_conversation_empty)
.setCustomAdapter(customAdapter)
.setCustomFragment(myConversationListFragment)
.build()
```
ChatUIKitConversationListFragment#Builder 提供的方法解释:
| 方法 | 说明 |
| -------------------------------- | ------------------------------------------------------------ |
| useTitleBar() | 是否使用默认的标题栏(ChatUIKitTitleBar)。
- true:是。
- (默认) false: 否。 |
| setTitleBarTitle() | 设置标题栏的标题。 |
| enableTitleBarPressBack() | 设置是否支持显示返回按钮,默认为不显示返回按钮。
- true:是。
- (默认) false: 否。 |
| setTitleBarBackPressListener() | 设置点击标题栏返回按钮的监听器。 |
| setItemClickListener() | 设置条目点击事件监听器。 |
| setOnItemLongClickListener() | 设置条目长按事件监听器。 |
| setOnMenuItemClickListener() | 设置条目菜单点击事件监听器。 |
| setConversationChangeListener() | 设置会话变化的监听器。 |
| setEmptyLayout() | 设置会话列表的空白页面。 |
| setCustomAdapter() | 设置自定义的适配器,默认为 ChatUIKitConversationListAdapter。 |
| setCustomFragment() | 设置自定义聊天 Fragment,需要继承自 ChatUIKitConversationListFragment。 |
#### 添加自定义会话布局
开发者可以继承 ChatUIKitConversationListAdapter 实现自己的 CustomConversationListAdapter ,然后将 CustomConversationListAdapter 设置到 ChatUIKitConversationListFragment#Builder#setCustomAdapter 中。
(1)创建自定义适配器 CustomConversationListAdapter ,继承自 ChatUIKitConversationListAdapter ,重写 getViewHolder 和 getItemNotEmptyViewType 方法。
```kotlin
class CustomConversationListAdapter : ChatUIKitConversationListAdapter() {
override fun getItemNotEmptyViewType(position: Int): Int {
// 根据消息类型设置自定义 itemViewType。
// 如果使用默认的 itemViewTyp,返回 super.getItemNotEmptyViewType(position) 即可。
return CUSTOM_YOUR_CONVERSATION_TYPE
}
override fun getViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
// 根据返回的 viewType 返回对应的 ViewHolder。
// 返回自定义的 ViewHolder 或者使用默认的 super.getViewHolder(parent, viewType)
return CUSTOM_YOUR_VIEW_HOLDER()
}
}
```
(2)添加 CustomConversationListAdapter 到 ChatUIKitConversationListFragment#Builder。
```kotlin
builder.setCustomAdapter(customConversationListAdapter);
```
#### 通过继承 ChatUIKitConversationListFragment 进行自定义设置
创建自定义 CustomConversationListFragment ,继承自 ChatUIKitConversationListFragment ,并设置到 ChatUIKitConversationListFragment#Builder 中。
```kotlin
builder.setCustomFragment(customConversationListFragment);
```
开发者可以通过在 CustomConversationListFragment 中获取到 ChatUIKitConversationListLayout 对象,可以进行更加细致的自定义设置。
ChatUIKitConversationListLayout 提供的方法解释:
| 方法 | 说明 |
| -------------------------------------- | ---------------------------------------------------------------- |
| setViewModel() | UIKit 中提供了默认的实现 ChatUIKitConversationListViewModel,开发者可以继承 IConversationListRequest 添加自己的数据逻辑。 |
| setListAdapter() | 设置自定义会话列表适配器。 |
| getListAdapter() | 获取会话列表适配器。 |
| getItem() | 获取指定位置的数据。 |
| makeConversionRead() | 将指定位置的会话置为已读。 |
| makeConversationTop() | 将指定位置的会话置顶。 |
| cancelConversationTop() | 取消指定位置的置顶操作。 |
| deleteConversation() | 删除置顶位置的会话。 |
| setOnConversationChangeListener() | 设置会话变化的监听,ChatUIKitConversationListFragment#Builder 提供了相应的设置方法。 |
| addHeaderAdapter() | 添加会话列表的头布局的适配器。 |
| addFooterAdapter() | 添加会话列表的尾布局的适配器。 |
| removeAdapter() | 移除指定适配器。 |
| addItemDecoration() | 添加会话列表的装饰器。 |
| removeItemDecoration() | 移除会话列表的装饰器。 |
| setOnItemClickListener() | 设置会话列表的条目点击监听,ChatUIKitConversationListFragment#Builder 提供了相应的设置方法。 |
| setOnItemLongClickListener() | 设置会话列表的条目长按监听。 |
| setItemBackGround() | 设置条目的背景。 |
| setItemHeight() | 设置条目的高度。 |
| setAvatarDefaultSrc() | 设置条目的默认头像。 |
| setAvatarSize() | 设置条目头像的大小。 |
| setAvatarShapeType() | 设置条目头像的样式,分为默认 ImageView 样式,圆形和矩形三种样式。 |
| setAvatarRadius() | 设置条目头像的圆角半径,样式设置为矩形时有效。 |
| setAvatarBorderWidth() | 设置条目头像边框的宽度。 |
| setAvatarBorderColor() | 设置条目头像边框的颜色。 |
| setNameTextSize() | 设置会话条目标题的文字大小。 |
| setNameTextColor() | 设置会话条目标题的文字颜色。 |
| setMessageTextSize() | 设置会话条目内容的文字大小。 |
| setMessageTextColor() | 设置会话条目内容的文字颜色。 |
| setDateTextSize() | 设置会话条目日期的文字大小。 |
| setDateTextColor() | 设置会话条目日期的文字颜色。 |
| clearMenu() | 清除长按菜单项。 |
| addItemMenu() | 添加长按菜单项。 |
| findItemVisible() | 设置指定菜单项是否可见。 |
### 联系人列表页面相关
#### 通过 ChatUIKitContactsListFragment.Builder 自定义设置
ChatUIKitContactsListFragment 提供了 Builder 构建方式,方便开发者进行一些自定义设置,目前提供的设置项如下:
```kotlin
ChatUIKitContactsListFragment.Builder()
.useTitleBar(true)
.setTitleBarTitle("title")
.enableTitleBarPressBack(true)
.setTitleBarBackPressListener(onBackPressListener)
.useSearchBar(false)
.setSearchType(ChatUIKitSearchType.USER)
.setListViewType(ChatUIKitListViewType.VIEW_TYPE_LIST_CONTACT)
.setSideBarVisible(true)
.setHeaderItemVisible(true)
.setHeaderItemList(mutableListOf())
.setOnHeaderItemClickListener(OnHeaderItemClickListener)
.setOnUserListItemClickListener(OnUserListItemClickListener)
.setOnItemLongClickListener(onItemLongClickListener)
.setOnContactSelectedListener(OnContactSelectedListener)
.setEmptyLayout(R.layout.layout_conversation_empty)
.setCustomAdapter(customAdapter)
.setCustomFragment(myContactsListFragment)
.build()
```
ChatUIKitContactsListFragment#Builder 提供的方法解释:
| 方法 | 说明 |
|----------------------------------|-----------------------------------------------------------------------------------------------|
| useTitleBar() | 是否使用默认的标题栏(ChatUIKitTitleBar)。
- true:是。
- (默认) false: 否。 |
| setTitleBarTitle() | 设置标题栏的标题。 |
| enableTitleBarPressBack() | 设置是否支持显示返回按钮,默认为不显示返回按钮。
- true:是。
- (默认) false: 否。 |
| setTitleBarBackPressListener() | 设置点击标题栏返回按钮的监听器。 |
| useSearchBar() | 设置是否使用搜索栏 默认为不显示。
- true:是。
- (默认) false: 否。 |
| setSearchType() | 设置搜索类型 ChatUIKitSearchType
- USER
- SELECT_USER
- CONVERSATION |
| setListViewType() | 设置列表类型 ChatUIKitListViewType
- LIST_CONTACT(默认 联系人列表)
- LIST_SELECT_CONTACT (带checkbox的联系人列表) |
| setSideBarVisible() | 设置是否显示首字母索引工具栏。 默认为显示工具栏。
- (默认) true:是。
- false: 否。 |
| setHeaderItemVisible() | 设置是否显示列表头部布局。 |
| setHeaderItemList() | 设置列表头部Item数据对象列表。 |
| setOnHeaderItemClickListener() | 设置列表头部Item点击事件。 |
| setOnUserListItemClickListener() | 设置列表条目点击事件。 |
| setOnItemLongClickListener() | 设置条目长按事件监听器。 |
| setOnContactSelectedListener() | 设置条目选中事件监听器。 |
| setEmptyLayout() | 设置会话列表的空白页面。 |
| setCustomAdapter() | 设置自定义的适配器,默认为 ChatUIKitConversationListAdapter。 |
| setCustomFragment() | 设置自定义聊天 Fragment,需要继承自 ChatUIKitConversationListFragment。 |
#### 添加自定义联系人布局
开发者可以继承 ChatUIKitContactListAdapter 实现自己的 CustomContactListAdapter ,然后将 CustomContactListAdapter 设置到 ChatUIKitContactsListFragment#Builder#setCustomAdapter 中。
(1)创建自定义适配器 CustomContactListAdapter ,继承自 ChatUIKitContactListAdapter ,重写 getViewHolder 和 getItemNotEmptyViewType 方法。
```kotlin
class CustomContactListAdapter : ChatUIKitContactListAdapter() {
override fun getItemNotEmptyViewType(position: Int): Int {
// 根据消息类型设置自定义 itemViewType。
// 如果使用默认的 itemViewTyp,返回 super.getItemNotEmptyViewType(position) 即可。
return CUSTOM_YOUR_CONTACT_TYPE
}
override fun getViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
// 根据返回的 viewType 返回对应的 ViewHolder。
// 返回自定义的 ViewHolder 或者使用默认的 super.getViewHolder(parent, viewType)
return CUSTOM_YOUR_VIEW_HOLDER()
}
}
```
(2)添加 CustomContactListAdapter 到 ChatUIKitContactsListFragment#Builder。
```kotlin
builder.setCustomAdapter(CustomContactListAdapter)
```
开发者可以通过在 CustomContactListFragment 中获取到 ChatUIKitContactsListFragment 对象,可以进行更加细致的自定义设置。
ChatUIKitContactListLayout 提供的方法解释:
| 方法 | 说明 |
| -------------------------------------- | ---------------------------------------------------------------- |
| setViewModel() | UIKit 中提供了默认的实现 ChatUIKitConversationListViewModel,开发者可以继承 IConversationListRequest 添加自己的数据逻辑。 |
| setListAdapter() | 设置自定义会话列表适配器。 |
| getListAdapter() | 获取会话列表适配器。 |
| getItem() | 获取指定位置的数据。 |
| addHeaderAdapter() | 添加会话列表的头布局的适配器。 |
| addFooterAdapter() | 添加会话列表的尾布局的适配器。 |
| removeAdapter() | 移除指定适配器。 |
| addItemDecoration() | 添加会话列表的装饰器。 |
| removeItemDecoration() | 移除会话列表的装饰器。 |
| setOnItemClickListener() | 设置会话列表的条目点击监听,ChatUIKitConversationListFragment#Builder 提供了相应的设置方法。 |
| setOnItemLongClickListener() | 设置会话列表的条目长按监听。 |
## UIKit 提供的全局配置
单群聊 UIKit 提供了一些全局配置,可以在初始化时进行设置,示例代码如下:
```kotlin
val avatarConfig = ChatUIKitAvatarConfig()
// Set the avatars are round shape
avatarConfig.avatarShape = ChatUIKitImageView.ShapeType.ROUND
val config = ChatUIKitConfig(avatarConfig = avatarConfig)
ChatUIKitClient.init(this, options, config)
```
ChatUIKitAvatarConfig 提供的配置项解释:
| 属性 | 说明 |
| -------------------------------------- | ---------------------------------------------------------------- |
| avatarShape | 头像样式,有默认,圆形和矩形三种样式,默认样式为默认。 |
| avatarRadius | 头像圆角半径,仅在头像样式设置为矩形后有效。 |
| avatarBorderColor | 头像边框的颜色。 |
| avatarBorderWidth | 头像边框的宽度。 |
ChatUIKitConfig 提供的配置项解释:
| 属性 | 说明 |
| -------------------------------------- | ---------------------------------------------------------------- |
| enableReplyMessage | 消息回复功能是否可用,默认为可用。 |
| enableModifyMessageAfterSent | 消息编辑功能是否可用,默认为可用。 |
| timePeriodCanRecallMessage | 设置消息可撤回的时间,默认为2分钟。 |
ChatUIKitDateFormatConfig 提供的配置项解释:
| 属性 | 说明 |
| -------------------------------------- | ---------------------------------------------------------------- |
| convTodayFormat | 会话列表当天日期格式,英文环境默认为:"HH:mm" |
| convOtherDayFormat | 会话列表其他日期的格式,英文环境默认为: "MMM dd" |
| convOtherYearFormat | 会话列表其他年日期的格式,英文环境默认为: "MMM dd, yyyy" |
ChatUIKitSystemMsgConfig 提供的配置项解释:
| 属性 | 说明 |
| -------------------------------------- | ---------------------------------------------------------------- |
| useDefaultContactInvitedSystemMsg | 是否启用系统消息功能,默认为启用。 |
ChatUIKitMultiDeviceEventConfig 提供的配置项解释:
| 属性 | 说明 |
|--------------------------------------|-------------------|
| useDefaultMultiDeviceContactEvent | 是否启用默认的多设备联系人事件处理 |
| useDefaultMultiDeviceGroupEvent | 是否启用默认的多设备群组事件处理 |
## UIKit 用户信息相关
UIKit 中多个地方用到用户信息,而这些用户信息需要开发者进行提供,本节将逐步介绍开发者如何提供给 UIKit 用户信息。
### 当前登录用户信息
用户调用登录接口 `ChatUIKitClient.login` 时需要传入一个 `ChatUIKitProfile` 的对象,包含 `id`, `name` 和 `avatar` 三个属性。`id` 是必须设置的参数,`name` 和 `avatar` 将用于当前用户昵称和头像的展示。并在发送消息时,将`name` 和 `avatar`属性设置到消息的`ext`中,方便其他用户进行展示。
如果登录时没有传入 `name` 和 `avatar` 属性,可以在登录后,调用 `ChatUIKitClient.updateCurrentUser` 对当前用户的信息进行更新。
### 联系人信息提供
UIKit 提供了接口 `ChatUIKitClient.setUserProfileProvider` 进行联系人信息的提供。
`ChatUIKitUserProfileProvider` 接口如下:
```kotlin
interface ChatUIKitUserProfileProvider {
// 同步获取联系人信息
fun getUser(userId: String?): ChatUIKitProfile?
// 异步获取联系人信息
fun fetchUsers(userIds: List, onValueSuccess: OnValueSuccess>)
}
```
用法如下:
```kotlin
ChatUIKitClient.setUserProfileProvider(object : ChatUIKitUserProfileProvider {
// 同步获取用户信息
override fun getUser(userId: String?): ChatUIKitProfile? {
return getLocalUserInfo(userId)
}
override fun fetchUsers(
userIds: List,
onValueSuccess: OnValueSuccess>
) {
fetchUserInfoFromServer(idsMap, onValueSuccess)
}
})
```
### 群组成员信息提供
UIKit 提供了接口 `ChatUIKitClient.setGroupProfileProvider` 进行联系人信息的提供。
`ChatUIKitGroupProfileProvider` 接口如下:
```kotlin
interface ChatUIKitGroupProfileProvider {
// 同步获取群成员信息
fun getGroup(id: String?): ChatUIKitGroupProfile?
// 异步获取群成员信息
fun fetchGroups(groupIds: List, onValueSuccess: OnValueSuccess>)
}
```
用法如下:
```kotlin
ChatUIKitClient.setGroupProfileProvider(object : ChatUIKitGroupProfileProvider {
override fun getGroup(id: String?): ChatUIKitGroupProfile? {
ChatClient.getInstance().groupManager().getGroup(id)?.let {
return ChatUIKitGroupProfile(it.groupId, it.groupName, it.extension)
}
return null
}
override fun fetchGroups(
groupIds: List,
onValueSuccess: OnValueSuccess>
) {
}
})
```
### UIKit 信息处理逻辑
- 如果信息已经缓存到内存,当页面需要显示信息时,UIKit 会首先从内存中查询获取到缓存数据并进行页面的渲染。如果缓存没有,则进入下一步。
- UIKit 调用 provider 同步方法从应用本地获取信息,开发者可以从应用本地的数据库或者内存中获取并提供对应信息。UIKit获取到信息后进行页面的渲染。同时,对获取到的信息进行缓存。
- 如果同步方法获取数据为空,当列表页面停止滑动的时候,UIKit 会将当前页面可见的条目所需的信息,在排除缓存和同步方法提供的数据后,通过 provider 提供的异步方法返给开发者,开发者从服务器获取对应的信息后,通过 `onValueSuccess` 提供给 UIKit。UIKit 收到数据后,会对列表进行刷新并更新对应的数据。
### 更新 UIKit 缓存信息
因为 UIKit 会对信息进行缓存,如果用户的信息发生改变,可以通过 UIKit 提供的 update 方法对缓存信息进行更新。
```kotlin
// 通过 ChatUIKitClient.getCache().getUser | ChatUIKitClient.getCache().getGroup 获取本地缓存对象进行更新赋值,之后调用update方法:
// 更新当前用户信息 user: ChatUIKitProfile
ChatUIKitClient.updateCurrentUser(user)
// 更新用户信息 list: List
ChatUIKitClient.updateUsersInfo(list)
// 更新群组信息 groups: List
ChatUIKitClient.updateGroupInfo(groups)
```
## UIKit 对明暗主题的支持
UIKit 对明暗主题进行了支持,会随系统设置明暗主题进行对应的颜色变化。如果要修改对应的颜色变化,可以在app module中新建 `values-night` 文件夹,并复制 `uikit_colors.xml` 到文件夹中,然后对其中的基础颜色修改,在暗色主题下,对应的颜色也会被修改。