English | 中文
单群聊 UIKit,是基于环信 IM SDK 的一款 UI 组件库,它提供了一些通用的 UI 组件,例如‘会话列表’、‘聊天界面’和‘联系人列表’等,开发者可根据实际业务需求通过该组件库快速地搭建自定义 IM 应用。单群聊 UIKit 中的组件在实现 UI 功能的同时,调用 IM SDK 相应的接口实现 IM 相关逻辑和数据的处理,因而开发者在 UIKit 时只需关注自身业务或个性化扩展即可。
本指南提供了 chat_uikit 框架在Android开发中的概述和使用示例,并介绍了此 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 源码集成。
在项目根目录的 build.gradle 或者 build.gradle.kts 文件中添加 MavenCentral 远程仓库。
buildscript {
repositories {
...
mavenCentral()
}
}
allprojects {
repositories {
...
mavenCentral()
}
}
在项目根目录的 settings.gradle
或者 settings.gradle.kts
文件中检查并添加 MavenCentral 远程仓库。
pluginManagement {
repositories {
...
mavenCentral()
}
}
dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositories {
...
mavenCentral()
}
}
在 app 项目 build.gradle.kts 中添加以下依赖
implementation("io.hyphenate:ease-chat-kit:4.11.1")
从 github 获取 Chat UIKit 源码,按照下面的方式集成:
- 在根目录 settings.gradle.kts 文件(/Gradle Scripts/settings.gradle.kts(Project Settings))中添加如下代码:
include(":ease-chat-kit")
project(":ease-chat-kit").projectDir = File("../chatuikit-android/ease-im-kit")
- 在
build.gradle.kts
文件(/Gradle Scripts/build.gradle(Module: app))中添加如下代码:
//chatuikit-android
implementation(project(mapOf("path" to ":ease-chat-kit")))
在 app/proguard-rules.pro
文件中添加如下行,防止代码混淆:
-keep class com.hyphenate.** {*;}
-dontwarn com.hyphenate.**
└── easeui
├── 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
<!-- IM SDK required start -->
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<!-- IM SDK required end -->
<!-- IM UIKit required start -->
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" android:maxSdkVersion="32" />
<!-- Android 13 to replace READ_EXTERNAL_STORAGE permission -->
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES"/>
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO"/>
<!-- Android 14 is used to grant partial access to photos and videos -->
<uses-permission android:name="android.permission.READ_MEDIA_VISUAL_USER_SELECTED"/>
<!-- IM UIKit required end -->
使用单群聊 UIKit 需要进行初始化,示例代码如下:
val options = ChatOptions()
options.appKey = "[Your appkey]"
ChatUIKitClient.init(this, options)
val user = ChatUIKitProfile(userName, nickname, avatarUrl)
ChatUIKitClient.login(user, token
, onSuccess = {
// Add success logic
}, onError = { code, error ->
// Add error logic
}
)
ChatUIKitClient.logout(unbindDeviceToken
, onSuccess = {
// Add success logic
}, onError = { code, error ->
// Add error logic
}
)
单群聊 UIKit 提供了 UIKitChatActivity 页面,调用 UIKitChatActivity#actionStart 方法即可,示例代码如下:
// 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 页面主要进行了权限的请求,比如相机权限,语音权限等。
开发者也可以使用 UIKit 提供的 UIKitChatFragment 创建聊天页面,示例代码如下:
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 中即可使用。
示例如下:
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 中即可使用。
示例如下:
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 构建方式,方便开发者进行一些自定义设置,目前提供的设置项如下:
// conversationID: 1v1 is peer's userID, group chat is groupID
// easeChatType: SINGLE_CHAT, GROUP_CHAT, CHATROOM
UIKitChatFragment.Builder(conversationID, easeChatType)
.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() | 设置自定义的适配器,默认为 EaseMessageAdapter。 |
setCustomFragment() | 设置自定义聊天 Fragment,需要继承自 UIKitChatFragment。 |
开发者可以继承 EaseMessageAdapter , ChatUIKitRowViewHolder 和 ChatUIKitRow 实现自己的 CustomMessageAdapter ,CustomChatTypeViewViewHolder 和 CustomTypeChatRow ,然后将 CustomMessageAdapter 设置到 UIKitChatFragment#Builder#setCustomAdapter 中。
(1)创建自定义适配器 CustomMessageAdapter 继承自 EaseMessageAdapter,重写 getViewHolder 和 getItemNotEmptyViewType 方法。
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<EaseMessage> {
// 根据返回的 viewType 返回对应的 ViewHolder。
// 返回自定义的 ViewHolder 或者 使用默认的 super.getViewHolder(parent, viewType)
return CUSTOM_VIEW_HOLDER()
}
}
(2)创建 CustomTypeChatRow ,继承自 ChatUIKitRow。
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。
class CustomChatTypeViewViewHolder(
itemView: View
): ChatUIKitRowViewHolder(itemView) {
override fun onBubbleClick(message: EaseMessage?) {
super.onBubbleClick(message)
// Add click event
}
}
(4)完善 CustomMessageAdapter。
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<EaseMessage> {
// 根据返回的 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。
builder.setCustomAdapter(CustomMessageAdapter())
创建自定义 CustomChatFragment,继承自 UIKitChatFragment,并设置到 UIKitChatFragment#Builder 中。
builder.setCustomFragment(customChatFragment)
(1)列表控件相关功能设置
获取 ChatUIKitMessageListLayout
对象:
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)扩展功能设置
val chatExtendMenu: IChatExtendMenu? = binding?.layoutChat?.chatInputMenu?.chatExtendMenu
拿到 chatExtendMenu 对象后,可以对于扩展功能可以进行添加,移除,排序以及处理扩展功能的点击事件等。
IChatExtendMenu 提供的方法解释:
方法 | 说明 |
---|---|
clear() | 清除所有的扩展菜单项 |
setMenuOrder() | 对指定的菜单项进行排序 |
registerMenuItem() | 添加新的菜单项 |
- 监听扩展条目点击事件
开发者可以 UIKitChatFragment#Builder#setOnChatExtendMenuItemClickListener 进行监听,也可以在自定义的 Fragment 中 重写 onChatExtendMenuItemClick 方法。
override fun onChatExtendMenuItemClick(view: View?, itemId: Int): Boolean {
if(itemId == CUSTOM_YOUR_EXTEND_MENU_ID) {
// 处理你自己的点击事件逻辑
// 如果要消费点击事件需要返回 true
return true
}
return super.onChatExtendMenuItemClick(view, itemId)
}
(3)长按菜单功能设置
- 增加自定义菜单条目
binding?.let {
it.layoutChat.addItemMenu(menuId, menuOrder, menuTile)
}
ChatUIKitLayout 提供的长按菜单方法
方法 | 说明 |
---|---|
clearMenu() | 清除菜单项。 |
addItemMenu() | 添加新的菜单项。 |
findItemVisible() | 通过指定 itemId 设置菜单项的可见性。 |
setOnMenuChangeListener() | 设置菜单项的点击事件监听,UIKitChatFragment 中已经设置此监听。 |
- 处理菜单的事件 在自定义的 Fragment 中重写以下方法:
override fun onPreMenu(helper: ChatUIKitChatMenuHelper?, message: ChatMessage?) {
// 菜单展示前的回调事件,可以通过 helper 对象在这里设置菜单条目是否展示。
}
override fun onMenuItemClick(item: ChatUIKitMenuItem?, message: ChatMessage?): Boolean {
// 如果要拦截某个点击事件,需要设置返回 true。
return false
}
override fun onDismiss() {
// 可以在这里处理快捷菜单的隐藏事件。
}
(4)设置输入菜单相关属性
- 获取 ChatUIKitInputMenu 对象
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 | 获取顶部扩展功能接口 |
- 获取菜单项对象
val primaryMenu: IChatPrimaryMenu? = binding?.layoutChat?.chatInputMenu?.chatPrimaryMenu
IChatPrimaryMenu 提供了如下方法:
方法 | 说明 |
---|---|
onTextInsert() | 在光标处插入文本 |
editText | 获取菜单输入框对象 |
setMenuBackground() | 设置菜单的背景 |
- 获取表情菜单对象
val emojiconMenu: IChatEmojiconMenu? = binding?.layoutChat?.chatInputMenu?.chatEmojiMenu
IChatEmojiconMenu 提供了如下方法:
方法 | 说明 |
---|---|
addEmojiconGroup() | 添加自定义表情 |
removeEmojiconGroup() | 移除指定的表情组 |
setTabBarVisibility() | 设置 TabBar 可见性 |
添加自定义表情
binding?.let {
it.layoutChat.chatInputMenu?.chatEmojiMenu?.addEmojiconGroup(EmojiconExampleGroupData.getData())
}
ChatUIKitConversationListFragment 提供了 Builder 构建方式,方便开发者进行一些自定义设置,目前提供的设置项如下:
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 方法。
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<ChatUIKitConversation> {
// 根据返回的 viewType 返回对应的 ViewHolder。
// 返回自定义的 ViewHolder 或者使用默认的 super.getViewHolder(parent, viewType)
return CUSTOM_YOUR_VIEW_HOLDER()
}
}
(2)添加 CustomConversationListAdapter 到 ChatUIKitConversationListFragment#Builder。
builder.setCustomAdapter(customConversationListAdapter);
创建自定义 CustomConversationListFragment ,继承自 ChatUIKitConversationListFragment ,并设置到 ChatUIKitConversationListFragment#Builder 中。
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()
.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<ChatUIKitCustomHeaderItem>())
.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 方法。
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<ChatUIKitUser> {
// 根据返回的 viewType 返回对应的 ViewHolder。
// 返回自定义的 ViewHolder 或者使用默认的 super.getViewHolder(parent, viewType)
return CUSTOM_YOUR_VIEW_HOLDER()
}
}
(2)添加 CustomContactListAdapter 到 ChatUIKitContactsListFragment#Builder。
builder.setCustomAdapter(CustomContactListAdapter)
开发者可以通过在 CustomContactListFragment 中获取到 ChatUIKitContactsListFragment 对象,可以进行更加细致的自定义设置。
ChatUIKitContactListLayout 提供的方法解释:
方法 | 说明 |
---|---|
setViewModel() | UIKit 中提供了默认的实现 ChatUIKitConversationListViewModel,开发者可以继承 IConversationListRequest 添加自己的数据逻辑。 |
setListAdapter() | 设置自定义会话列表适配器。 |
getListAdapter() | 获取会话列表适配器。 |
getItem() | 获取指定位置的数据。 |
addHeaderAdapter() | 添加会话列表的头布局的适配器。 |
addFooterAdapter() | 添加会话列表的尾布局的适配器。 |
removeAdapter() | 移除指定适配器。 |
addItemDecoration() | 添加会话列表的装饰器。 |
removeItemDecoration() | 移除会话列表的装饰器。 |
setOnItemClickListener() | 设置会话列表的条目点击监听,ChatUIKitConversationListFragment#Builder 提供了相应的设置方法。 |
setOnItemLongClickListener() | 设置会话列表的条目长按监听。 |
单群聊 UIKit 提供了一些全局配置,可以在初始化时进行设置,示例代码如下:
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 用户信息。
用户调用登录接口 ChatUIKitClient.login
时需要传入一个 ChatUIKitProfile
的对象,包含 id
, name
和 avatar
三个属性。id
是必须设置的参数,name
和 avatar
将用于当前用户昵称和头像的展示。并在发送消息时,将name
和 avatar
属性设置到消息的ext
中,方便其他用户进行展示。
如果登录时没有传入 name
和 avatar
属性,可以在登录后,调用 ChatUIKitClient.updateCurrentUser
对当前用户的信息进行更新。
UIKit 提供了接口 ChatUIKitClient.setUserProfileProvider
进行联系人信息的提供。
ChatUIKitUserProfileProvider
接口如下:
interface ChatUIKitUserProfileProvider {
// 同步获取联系人信息
fun getUser(userId: String?): ChatUIKitProfile?
// 异步获取联系人信息
fun fetchUsers(userIds: List<String>, onValueSuccess: OnValueSuccess<List<ChatUIKitProfile>>)
}
用法如下:
ChatUIKitClient.setUserProfileProvider(object : ChatUIKitUserProfileProvider {
// 同步获取用户信息
override fun getUser(userId: String?): ChatUIKitProfile? {
return getLocalUserInfo(userId)
}
override fun fetchUsers(
userIds: List<String>,
onValueSuccess: OnValueSuccess<List<ChatUIKitProfile>>
) {
fetchUserInfoFromServer(idsMap, onValueSuccess)
}
})
UIKit 提供了接口 ChatUIKitClient.setGroupProfileProvider
进行联系人信息的提供。
ChatUIKitGroupProfileProvider
接口如下:
interface ChatUIKitGroupProfileProvider {
// 同步获取群成员信息
fun getGroup(id: String?): ChatUIKitGroupProfile?
// 异步获取群成员信息
fun fetchGroups(groupIds: List<String>, onValueSuccess: OnValueSuccess<List<ChatUIKitGroupProfile>>)
}
用法如下:
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<String>,
onValueSuccess: OnValueSuccess<List<ChatUIKitGroupProfile>>
) {
}
})
- 如果信息已经缓存到内存,当页面需要显示信息时,UIKit 会首先从内存中查询获取到缓存数据并进行页面的渲染。如果缓存没有,则进入下一步。
- UIKit 调用 provider 同步方法从应用本地获取信息,开发者可以从应用本地的数据库或者内存中获取并提供对应信息。UIKit获取到信息后进行页面的渲染。同时,对获取到的信息进行缓存。
- 如果同步方法获取数据为空,当列表页面停止滑动的时候,UIKit 会将当前页面可见的条目所需的信息,在排除缓存和同步方法提供的数据后,通过 provider 提供的异步方法返给开发者,开发者从服务器获取对应的信息后,通过
onValueSuccess
提供给 UIKit。UIKit 收到数据后,会对列表进行刷新并更新对应的数据。
因为 UIKit 会对信息进行缓存,如果用户的信息发生改变,可以通过 UIKit 提供的 update 方法对缓存信息进行更新。
// 通过 ChatUIKitClient.getCache().getUser | ChatUIKitClient.getCache().getGroup 获取本地缓存对象进行更新赋值,之后调用update方法:
// 更新当前用户信息 user: ChatUIKitProfile
ChatUIKitClient.updateCurrentUser(user)
// 更新用户信息 list: List<ChatUIKitProfile>
ChatUIKitClient.updateUsersInfo(list)
// 更新群组信息 groups: List<ChatUIKitGroupProfile>
ChatUIKitClient.updateGroupInfo(groups)
UIKit 对明暗主题进行了支持,会随系统设置明暗主题进行对应的颜色变化。如果要修改对应的颜色变化,可以在app module中新建 values-night
文件夹,并复制 uikit_colors.xml
到文件夹中,然后对其中的基础颜色修改,在暗色主题下,对应的颜色也会被修改。