English | 中文
This guide gives a comprehensive overview into chat_uikit. The new chat_uikit is intended to provide developers with an efficient, plug-and-play, and highly customizable UI component library, helping you build complete and elegant IM applications that can easily satisfy most instant messaging scenarios. Please download the demo to try it out.
This guide provides an overview and usage examples of the chat_uikit framework in Android development, and presents various components and functions of this UIKit, giving developers a good understanding of how chat_uikit works and how to use it efficiently.
- Chat UIKit Readme
- Table of contents
- Product Experience
- Development Environment
- Installation
- Basic project structure of chat_uikit
- Permission requirements
- Initialize and log in to the UIKit
- Create pages
- Advanced customization
- Global configurations
- User information
- Support for dark and light themes
In this project, there is a best-practice demonstration project in the app
folder for you to build your own business capabilities.
If you want to experience the functions of chat_uikit, you can scan the following QR code to try the demo.
- Android Studio Flamingo | 2022.2.1 or later
- Gradle 8.0 or later
- TargetVersion 26 or later
- Android SDK API 21 or later
- JDK 17 or later
The UIKit can be integrated with Gradle and module source code.
Add the Maven remote repository in build.gradle
or build.gradle.kts
in the root directory of the project.
buildscript {
repositories {
...
mavenCentral()
}
}
allprojects {
repositories {
...
mavenCentral()
}
}
Add the Maven remote repository in settings.gradle
or settings.gradle.kts
in the root directory of the project.
pluginManagement {
repositories {
...
mavenCentral()
}
}
dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositories {
...
mavenCentral()
}
}
Add the following dependency to build.gradle.kts
of the app project:
implementation("io.hyphenate:ease-chat-kit:4.8.1")
Acquire the Chat UIKit source code from the GitHub repository and integrate it in the following way:
- Add the following code in the
settings.gradle.kts
file (/Gradle Scripts/settings.gradle.kts(Project Settings)) in the root directory.
include(":chat-uikit")
project(":chat-uikit").projectDir = File("../chatuikit-android/ease-im-kit")
- Add the following code in
build.gradle.kts
(/Gradle Scripts/build.gradle(Module: app)).
//chat-uikit
implementation(project(mapOf("path" to ":chat-uikit")))
Add the following lines to app/proguard-rules.pro
to prevent code obfuscation.
-keep class com.hyphenate.** {*;}
-dontwarn com.hyphenate.**
└── uikit
├── EaseIM // UIKit SDK entry
├── EaseIMConfig // UIKit SDK configuration class
├── feature // UIKit function module
│ ├── chat // Chat module
│ │ ├── activities // Activity folder
│ │ │ └── EaseChatActivity // Chat page built in the UIKit
│ │ ├── adapter // Adapter folder of the chat module
│ │ │ └── EaseMessagesAdapter // Message list adapter
│ │ ├── controllers // Controller of all functions of the chat module
│ │ ├── pin // Message pinning
│ │ ├── urlpreview // URL preview
│ │ ├── reply // Message reply
│ │ ├── report // Message reporting
│ │ ├── chathistory // Chat history
│ │ ├── forward // Message forwarding
│ │ ├── reaction // Message reaction
│ │ ├── search // Message search
│ │ ├── translation // Message translation
│ │ ├── viewholders // Message type ViewHolder
│ │ ├── widgets // Custom view of the chat module
│ │ └── EaseChatFragment // Chat fragment built in the UIKit
│ ├── conversation // Conversation list module
│ │ ├── adapter // Adapter folder
│ │ │ └── EaseConversationListAdapter // Conversation list adapter
│ │ ├── viewholders // Conversation ViewHolder
│ │ ├── widgets // Custom view of the conversation list module
│ │ └── EaseConversationListFragment // Conversation list fragment built in the UIKit
│ ├── thread // Message thread module
│ │ ├── adapter // Adapter folder
│ │ │ └── EaseChatThreadListAdapter // Message thread list adapter
│ │ ├── viewholder // Message thread ViewHolder
│ │ ├── widgets // Custom view of the message thread module
│ │ └── EaseChatThreadActivity // Thread chat page within the UIKit
│ ├── contact // Contact list module
│ │ ├── adapter // Contact list adapter folder
│ │ │ └── EaseContactListAdapter // Contact list adapter
│ │ ├── viewholders // Contact ViewHolder
│ │ ├── widgets // Custom view of the contact list module
│ │ └── EaseContactsListFragment // Contact list fragment built in the UIKit
│ └── group // Group module
│ ├── fragments // Group fragment
│ ├── adapter // Adapter folder
│ │ └── EaseGroupListAdapter // Group list adapter
│ ├── viewholders // ViewHolder Message ViewHolder
│ └── EaseGroupListActivity // Group list UI built in the UIKit
├── repository // UIKit SDK data repository
├── viewmodel // UIKit SDK ViewModel
├── provider // UIKit SDK Provider
├── common // Public class of UIKit SDK
├── interfaces // API class of UIKit SDK
└── widget // Custom view of UIKit SDK
<!-- 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 -->
You need to initialize the UIKit before using it:
val options = ChatOptions()
options.appKey = "[Your appkey]"
EaseIM.init(this, options)
val user = EaseProfile(userName, nickname, avatarUrl)
EaseIM.login(user, token
, onSuccess = {
// Add success logic
}, onError = { code, error ->
// Add error logic
}
)
EaseIM.logout(unbindDeviceToken
, onSuccess = {
// Add success logic
}, onError = { code, error ->
// Add error logic
}
)
The UIKit provides the EaseChatActivity
page. You can call the EaseChatActivity#actionStart
method to create the chat page.
// conversationId: 1v1 is peer's userID, group chat is groupID
// chatType can be EaseChatType#SINGLE_CHAT, EaseChatType#GROUP_CHAT
EaseChatActivity.actionStart(mContext, conversationId, chatType)
The EaseChatActivity page requests permissions, like camera permissions and voice permissions.
Alternatively, you can create the chat page with EaseChatFragment
:
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 ChatType#SINGLE_CHAT, ChatType#GROUP_CHAT
EaseChatFragment.Builder(conversationId, chatType)
.build()?.let { fragment ->
supportFragmentManager.beginTransaction()
.replace(R.id.fl_fragment, fragment).commit()
}
}
}
UIKit provides EaseConversationListFragment
. You can create the conversation list page by adding EaseConversationListFragment
to the Activity
.
class ConversationListActivity: AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_conversation_list)
EaseConversationListFragment.Builder()
.build()?.let { fragment ->
supportFragmentManager.beginTransaction()
.replace(R.id.fl_fragment, fragment).commit()
}
}
}
UIKit provides EaseContactsListFragment
. You can create the contact list page by adding EaseContactsListFragment
to the Activity
.
class ContactListActivity: AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_contact_list)
EaseContactsListFragment.Builder()
.build()?.let { fragment ->
supportFragmentManager.beginTransaction()
.replace(R.id.fl_fragment, fragment).commit()
}
}
}
EaseChatFragment allows you to custom settings shown below with Builder:
EaseChatFragment
// conversationID: 1v1 is peer's userID, group chat is groupID
// easeChatType: SINGLE_CHAT, GROUP_CHAT
EaseChatFragment.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()
EaseChatFragment#Builder provides the following methods:
Method | Description |
---|---|
useTitleBar() | Sets to use the default title bar (EaseTitleBar): - true: Yes - (Default) false: No |
setTitleBarTitle() | Sets the title of the title bar. |
setTitleBarSubTitle() | Sets the sub-title of the title bar. |
enableTitleBarPressBack() | Sets whether to show the back button in the title bar: - true: Yes - (Default) false: No |
setTitleBarBackPressListener() | Sets the event that occurs when clicking the the back button in the title bar. |
setSearchMessageId() | Sets the message ID for search. If a match is found, EaseChatFragment will display the target message as well as 10 messages following it. |
getHistoryMessageFromServerOrLocal() | Sets whether to preferentially get messages from the server or local storage. |
setOnChatExtendMenuItemClickListener() | Sets the listener for chat extension items. |
setOnChatInputChangeListener() | Sets the listener for text changes on the menu. |
setOnMessageItemClickListener() | Sets the listener for item click events, like the click and long press events of a message cell and avatar. |
setOnMessageSendCallback() | Sets the message sending result callback. |
setOnWillSendMessageListener() | Sets the listener for adding message extension attributes before sending a message. |
setOnChatRecordTouchListener() | Sets the recording button touch event. |
setOnMessageForwardCallback() | Sets the message forwarding result callback. |
setOnSendCombineMessageCallback() | Sets the result callback of sending a combined message. |
setOnReactionMessageListener() | Sets the listener for message Reaction operation result. |
setOnModifyMessageListener() | Sets the listener for message edit result. |
setOnReportMessageListener() | Sets the listener for message reporting result. |
setOnTranslationMessageListener() | Sets the listener for message translation result. |
setMsgTimeTextColor() | Sets the color of the timeline. |
setMsgTimeTextSize() | Sets the font size of the timeline text. |
setReceivedMsgBubbleBackground() | Sets the background color of the received message cell. |
setSentBubbleBackground() | Sets the background color of the sent message cell. |
showNickname() | Sets whether to display the nickname: - true: Yes - (Default) false: No |
hideReceiverAvatar() | Sets to hide the recipient avatar. By default, the recipient avatar is displayed. |
hideSenderAvatar() | Sets to hide the sender avatar. By default, the sender avatar is displayed. |
setChatBackground() | Sets the background of the chat list section. |
setChatInputMenuBackground() | Sets the background of the input bar. |
setChatInputMenuHint() | Sets the hint in the text box in the input bar. |
sendMessageByOriginalImage() | Sets whether to send the original image for an image message: - true: Yes - (Default) false: No |
setThreadMessage() | Sets whether to set the current conversation as a thread conversation: - true: Yes - (Default) false: No |
setTargetTranslationList() | Sets the list of target languages for translation. You need to enable the translation function before calling this method. |
setEmptyLayout() | Sets the empty page for the chat list. |
setCustomAdapter() | Sets a custom adapter. By default, EaseMessageAdapter is used. |
setCustomFragment() | Sets the custom chat fragment by inheriting EaseChatFragment. |
You can create a CustomMessageAdapter, CustomChatTypeViewViewHolder, and CustomTypeChatRow by inheriting EaseMessageAdapter, EaseChatRowViewHolder, and EaseChatRow, and then set CustomMessageAdapter to EaseChatFragment#Builder#setCustomAdapter.
(1) You can create a CustomMessageAdapter by inheriting EaseMessageAdapter and overwrite getViewHolder
and getItemNotEmptyViewType
methods.
class CustomMessageAdapter: EaseMessagesAdapter() {
override fun getItemNotEmptyViewType(position: Int): Int {
// Set your own itemViewType by message type.
// To use the default message type, return super.getItemNotEmptyViewType(position).
return CUSTOM_YOUR_MESSAGE_TYPE
}
override fun getViewHolder(parent: ViewGroup, viewType: Int): ViewHolder<EaseMessage> {
// Return the ViewHolder for the returned viewType.
// Return the custom ViewHolder or use the default super.getViewHolder(parent, viewType).
return CUSTOM_VIEW_HOLDER()
}
}
(2) Create a CustomTypeChatRow by inheriting EaseChatRow.
class CustomTypeChatRow(
private val context: Context,
private val attrs: AttributeSet? = null,
private val defStyle: Int = 0,
isSender: Boolean = false
): EaseChatRow(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)Create a CustomChatTypeViewViewHolder by inheriting EaseChatRowViewHolder.
class CustomChatTypeViewViewHolder(
itemView: View
): EaseChatRowViewHolder(itemView) {
override fun onBubbleClick(message: EaseMessage?) {
super.onBubbleClick(message)
// Add click event
}
}
(4)Make improvement to CustomMessageAdapter.
class CustomMessageAdapter: EaseMessagesAdapter() {
override fun getItemNotEmptyViewType(position: Int): Int {
// Set your own itemViewType by message type.
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
}
}
}
}
// If the default message type is used, return super.getItemNotEmptyViewType(position).
return super.getItemNotEmptyViewType(position)
}
override fun getViewHolder(parent: ViewGroup, viewType: Int): ViewHolder<EaseMessage> {
// Return ViewHolder for the returned viewType.
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)
)
}
// Return the custom ViewHolder or use the default 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)Add CustomMessageAdapter in EaseChatFragment#Builder.
builder.setCustomAdapter(CustomMessageAdapter())
Create a CustomChatFragment by inheriting EaseChatFragment and set it in EaseChatFragment#Builder.
builder.setCustomFragment(customChatFragment)
(1) Set the functions of the list control
Get the EaseChatMessageListLayout
object:
val chatMessageListLayout:EaseChatMessageListLayout? = binding?.layoutChat?.chatMessageListLayout
EaseChatMessageListLayout provides the following methods:
Method | Description |
---|---|
setViewModel() | UIKit provides EaseMessageListViewModel. You can add your own data logic by inheriting IChatMessageListRequest. |
setMessagesAdapter() | Sets the message list adapter that is a subclass of EaseMessagesAdapter. |
getMessagesAdapter() | Returns the message list adapter. |
addHeaderAdapter() | Adds the adapter of the header adapter of the message list. |
addFooterAdapter() | Adds the adapter of the foot adapter of the message list. |
removeAdapter() | Removes a specific adapter. |
addItemDecoration() | Adds the decorator of the message list. |
removeItemDecoration() | Removes the decorator of the message list. |
setAvatarDefaultSrc() | Sets the default avatar of an item. |
setAvatarShapeType() | Sets the avatar style: default style, round, and rectangular. |
showNickname() | Sets whether to display the nickname of the item. Also, EaseChatFragment#Builder provides the method for this function. |
setItemSenderBackground() | Sets the background of the sender. Also, EaseChatFragment#Builder provides the method for this function. |
setItemReceiverBackground() | Sets the background of the recipient. Also, EaseChatFragment#Builder provides a method for this function. |
setItemTextSize() | Sets the font size of the text message. |
setItemTextColor() | Sets the font color of the text message. |
setTimeTextSize() | Sets the font size of the timeline text. Also, EaseChatFragment#Builder provides a method for this function. |
setTimeTextColor() | Sets the color of the timeline text. Also, EaseChatFragment#Builder provides a method for this function. |
setTimeBackground() | Sets the background of the timeline. |
hideChatReceiveAvatar() | Sets not to display the recipient's avatar. Also, EaseChatFragment#Builder provides a method for this function. |
hideChatSendAvatar() | Sets not to display the sender's avatar. Also, EaseChatFragment#Builder provides a method for this function. |
setOnChatErrorListener() | Sets the error listener for sending a message. Also, EaseChatFragment#Builder provides a method for this function. |
(2)Set extension functions
val chatExtendMenu: IChatExtendMenu? = binding?.layoutChat?.chatInputMenu?.chatExtendMenu
When getting the chatExtendMenu object, you can add, remove, and order extension functions and handle click events of these functions.
IChatExtendMenu provides the following methods:
Method | Description |
---|---|
clear() | Clears all extension menu items. |
setMenuOrder() | Order a specific menu item. |
registerMenuItem() | Add a new menu item. |
- Listen for the extension item click event.
You can use EaseChatFragment#Builder#setOnChatExtendMenuItemClickListener for listening for click events of extension items, or overwrite the onChatExtendMenuItemClick method in your custom fragment.
override fun onChatExtendMenuItemClick(view: View?, itemId: Int): Boolean {
if(itemId == CUSTOM_YOUR_EXTEND_MENU_ID) {
// Handle your own click event logic.
// To consume click events, you need to return `true`.
return true
}
return super.onChatExtendMenuItemClick(view, itemId)
}
(3)Set menu items upon long press.
- Add custom menu items.
binding?.let {
it.layoutChat.addItemMenu(menuId, menuOrder, menuTile)
}
EaseChatLayout provides the following method that can be called upon long press
Method | Description |
---|---|
clearMenu() | Clears menu items. |
addItemMenu() | Adds a new menu item. |
findItemVisible() | Sets whether a menu item is visible by itemId. |
setOnMenuChangeListener() | Sets a listener for click events of menu items. This listener is already set in EaseChatFragment. |
- Handle events relating to the menu. Overwrite the following method in a custom fragment:
override fun onPreMenu(helper: EaseChatMenuHelper?, message: ChatMessage?) {
// Callback event that occurs before the menu is displayed. Here you can set whether to display menu items by using the helper object.
}
override fun onMenuItemClick(item: EaseMenuItem?, message: ChatMessage?): Boolean {
// If you want to intercept a certain event, you need to set to return `true`.
return false
}
override fun onDismiss() {
// You can handle the shortcut menu hiding event here.
}
(4) Set the properties of the input menu.
- Get the EaseChatInputMenu object.
val chatInputMenu: EaseChatInputMenu? = binding?.layoutChat?.chatInputMenu
EaseChatInputMenu provides the following methods:
Method | Description |
---|---|
setCustomPrimaryMenu() | Sets a custom menu item, via View or Fragment. |
setCustomEmojiconMenu() | Sets a custom emoji, via View or Fragment |
setCustomExtendMenu() | Sets a custom extension function, via View, Dialog, or Fragment. |
setCustomTopExtendMenu() | Sets a custom top layout of the menu, via View or Fragment. |
hideExtendContainer() | Hides the extension area, including the emoji area and extension function area. |
hideInputMenu() | Hides the areas except the top area of the menu. |
showEmojiconMenu() | Displays the emoji function area. |
showExtendMenu() | Displays the extension function area. |
showTopExtendMenu() | Displays the top extension function area. |
setChatInputMenuListener() | Sets the input menu listener. |
chatPrimaryMenu | Gets menu items. |
chatEmojiMenu | Gets the emoji function menu. |
chatExtendMenu | Gets the extension function. |
chatTopExtendMenu | Gets the top extension function. |
- Gets the menu item object.
val primaryMenu: IChatPrimaryMenu? = binding?.layoutChat?.chatInputMenu?.chatPrimaryMenu
IChatPrimaryMenu provides the following methods:
Method | Description |
---|---|
onTextInsert() | Inserts texts at the cursor position. |
editText | Gets the input box object of the menu. |
setMenuBackground() | Sets the background of the menu. |
- Gets the emoji menu object.
val emojiconMenu: IChatEmojiconMenu? = binding?.layoutChat?.chatInputMenu?.chatEmojiMenu
IChatEmojiconMenu provides the following methods:
Method | Description |
---|---|
addEmojiconGroup() | Adds a custom emoji group. |
removeEmojiconGroup() | Removes a emoji group. |
setTabBarVisibility() | Sets the visibility of TabBar. |
Add custom emojis:
binding?.let {
it.layoutChat.chatInputMenu?.chatEmojiMenu?.addEmojiconGroup(EmojiconExampleGroupData.getData())
}
EaseConversationListFragment allows you to customize settings shown below with Builder.
EaseConversationListFragment.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()
EaseConversationListFragment#Builder provides the following methods:
Method | Description |
---|---|
useTitleBar() | Sets whether to use the default title bar (EaseTitleBar): - true: Yes -(Default) false: No |
setTitleBarTitle() | Sets the title of the title bar. |
enableTitleBarPressBack() | Sets whether to display the back button: - true: Yes -(Default) false: No |
setTitleBarBackPressListener() | Sets the listener for the click of the back button in the title bar. |
setItemClickListener() | Sets the item click event listener. |
setOnItemLongClickListener() | Sets the item long-pressing event listener. |
setOnMenuItemClickListener() | Sets the item click event listener. |
setConversationChangeListener() | Sets the conversation change listener. |
setEmptyLayout() | Sets a blank page. |
setCustomAdapter() | Sets a custom conversation list adapter by inheriting EaseConversationListAdapter. |
setCustomFragment() | Sets a custom chat fragment by inheriting EaseConversationListFragment. |
You can add a CustomConversationListAdapter by inheriting EaseConversationListAdapter and set CustomConversationListAdapter to EaseConversationListFragment#Builder#setCustomAdapter.
(1) Create a CustomConversationListAdapter by inheriting EaseConversationListAdapter, and overwrite the getViewHolder and getItemNotEmptyViewType methods.
class CustomConversationListAdapter : EaseConversationListAdapter() {
override fun getItemNotEmptyViewType(position: Int): Int {
// Set a custom itemViewType by message type.
// If the default itemViewTyp is used, return super.getItemNotEmptyViewType(position).
return CUSTOM_YOUR_CONVERSATION_TYPE
}
override fun getViewHolder(parent: ViewGroup, viewType: Int): ViewHolder<EaseConversation> {
// Return the ViewHolder by reference to the returned viewType.
// Return the custom ViewHolder or use the default super.getViewHolder(parent, viewType).
return CUSTOM_YOUR_VIEW_HOLDER()
}
}
(2)Add CustomConversationListAdapter in EaseConversationListFragment#Builder.
builder.setCustomAdapter(customConversationListAdapter);
Create a CustomConversationListFragment by inheriting EaseConversationListFragment and set it to EaseConversationListFragment#Builder.
builder.setCustomFragment(customConversationListFragment);
You can gets the EaseConversationListLayout object from CustomConversationListFragment and configure custom settings.
EaseConversationListLayout provides the following methods:
Method | Description |
---|---|
setViewModel() | UIKit provides the EaseConversationListViewModel. You can inherit IConversationListRequest and then add your own data logic. |
setListAdapter() | Sets a custom conversation list adapter. |
getListAdapter() | Gets a conversation list adapter. |
getItem() | Gets the data at the specific position. |
makeConversionRead() | Sets a conversation as read. |
makeConversationTop() | Pins a conversation. |
cancelConversationTop() | Unpins a conversation. |
deleteConversation() | Deletes a pinned conversation. |
setOnConversationChangeListener() | Sets a conversation change listener. Also, EaseConversationListFragment#Builder provides a method to set the listener. |
addHeaderAdapter() | Adds an adapter for the header layout of the conversation list. |
addFooterAdapter() | Adds an adapter for the footer layout of the conversation list. |
removeAdapter() | Removes an adapter. |
addItemDecoration() | Adds a conversation list decorator. |
removeItemDecoration() | Removes a conversation list decorator. |
setOnItemClickListener() | Sets an item click listener. Also, EaseConversationListFragment#Builder provides a method to set the listener. |
setOnItemLongClickListener() | Sets an item long-press listener. |
setItemBackGround() | Sets the item background. |
setItemHeight() | Sets the item height. |
setAvatarDefaultSrc() | Sets the default item avatar. |
setAvatarSize() | Sets the size of the item avatar. |
setAvatarShapeType() | Sets the item avatar style: default ImageView style, round, and rectangular. |
setAvatarRadius() | Sets the border radius of the item avatar. This setting is valid only for a rectangular avatar. |
setAvatarBorderWidth() | Sets the width of the item avatar frame. |
setAvatarBorderColor() | Sets the color of the item avatar frame. |
setNameTextSize() | Sets the font size of the conversation item title. |
setNameTextColor() | Sets the text color of the conversation item title. |
setMessageTextSize() | Sets the font size of message texts in the conversation item. |
setMessageTextColor() | Sets the color of message texts in the conversation item. |
setDateTextSize() | Sets the font size of the conversation item date. |
setDateTextColor() | Sets the text color of the conversation item date. |
clearMenu() | Clears menu items that appear when long pressing a conversation item. |
addItemMenu() | Adds a menu item that appears when long pressing a conversation item. |
findItemVisible() | Sets whether a menu item is visible. |
EaseContactsListFragment allows you to customize the settings shown below with Builder:
EaseContactsListFragment.Builder()
.useTitleBar(true)
.setTitleBarTitle("title")
.enableTitleBarPressBack(true)
.setTitleBarBackPressListener(onBackPressListener)
.useSearchBar(false)
.setSearchType(EaseSearchType.USER)
.setListViewType(EaseListViewType.VIEW_TYPE_LIST_CONTACT)
.setSideBarVisible(true)
.setDefaultMenuVisible(true)
.setHeaderItemVisible(true)
.setHeaderItemList(mutableListOf<EaseCustomHeaderItem>())
.setOnHeaderItemClickListener(OnHeaderItemClickListener)
.setOnUserListItemClickListener(OnUserListItemClickListener)
.setOnItemLongClickListener(onItemLongClickListener)
.setOnContactSelectedListener(OnContactSelectedListener)
.setEmptyLayout(R.layout.layout_conversation_empty)
.setCustomAdapter(customAdapter)
.setCustomFragment(myContactsListFragment)
.build()
EaseContactsListFragment#Builder provides the following methods:
Method | Description |
---|---|
useTitleBar() | Whether to use the default title bar (EaseTitleBar): - true: Yes - (Default) false: No |
setTitleBarTitle() | Sets the title in the title bar. |
enableTitleBarPressBack() | Sets whether to display the back button: - true: Yes - (Default) false: No |
setTitleBarBackPressListener() | Sets the listener for the click of the back button of the title bar. |
useSearchBar() | Sets whether to use the search bar: - true: Yes - (Default) false: No |
setSearchType() | Sets the search type EaseSearchType: - USER - SELECT_USER - CONVERSATION |
setListViewType() | Sets the contact list type EaseListViewType - LIST_CONTACT (contact list by default) - LIST_SELECT_CONTACT (contact list with checkboxes) |
setSideBarVisible() | Sets whether to display the initial index toolbar - (Default) true: Yes - false: No |
setDefaultMenuVisible() | Sets whether to show the default menu: - (Default) true: Yes - false: No |
setHeaderItemVisible() | Sets whether to show the contact list header layout: - true: Yes - (Default) false: No |
setHeaderItemList() | Sets the data object list of the header item of the contact list. |
setOnHeaderItemClickListener() | Sets the click event listener for a header item of the contact list. |
setOnUserListItemClickListener() | Sets the contact click event listener. |
setOnItemLongClickListener() | Sets the contact item long-press event listener. |
setOnContactSelectedListener() | Sets the contact item selection event listener. |
setEmptyLayout() | Sets the blank page. |
setCustomAdapter() | Sets a custom adapter by inheriting EaseContactListAdapter. |
setCustomFragment() | Sets a custom chat fragment by inheriting EaseContactListFragment. |
You can create a CustomContactListAdapter by inheriting EaseContactListAdapter and set CustomContactListAdapter in EaseContactsListFragment#Builder#setCustomAdapter.
(1) Create a CustomContactListAdapter by inheriting EaseContactListAdapter to overwrite getViewHolder and getItemNotEmptyViewType methods.
class CustomContactListAdapter : EaseContactListAdapter() {
override fun getItemNotEmptyViewType(position: Int): Int {
//Set a custom itemViewType by message type.
// If the default itemViewTyp is used, return super.getItemNotEmptyViewType(position).
return CUSTOM_YOUR_CONTACT_TYPE
}
override fun getViewHolder(parent: ViewGroup, viewType: Int): ViewHolder<EaseUser> {
// Return ViewHolder by reference to the returned viewType.
// Return the custom ViewHolder or use the default super.getViewHolder(parent, viewType)
return CUSTOM_YOUR_VIEW_HOLDER()
}
}
(2) Add CustomContactListAdapter to EaseContactsListFragment#Builder.
builder.setCustomAdapter(CustomContactListAdapter)
You can get the EaseContactsListFragment object from CustomContactListFragment and configure specific custom settings.
EaseContactListLayout provides the following methods:
Method | Description |
---|---|
setViewModel() | The UIKit provides EaseContactListViewModel. You can inherit IConversationListRequest to add your own data logic. |
setListAdapter() | Sets a custom contact list adapter. |
getListAdapter() | Gets the contact list adapter. |
getItem() | Gets the data at a specific location. |
addHeaderAdapter() | Adds the header layout adapter for the contact list. |
addFooterAdapter() | Adds the footer layout adapter for the contact list. |
removeAdapter() | Removes an adapter. |
addItemDecoration() | Adds a contact list decorator. |
removeItemDecoration() | Removes a contact list decorator. |
setOnItemClickListener() | Sets the contact item click listener. Also, EaseContactListFragment#Builder provides the method to set the listener. |
setOnItemLongClickListener() | Sets the item long-pressing listener. |
The UIKit provides global configurations which can be set during the initialization:
val avatarConfig = EaseAvatarConfig()
// Set the avatars are round shape
avatarConfig.avatarShape = EaseImageView.ShapeType.ROUND
val config = EaseIMConfig(avatarConfig = avatarConfig)
EaseIM.init(this, options, config)
EaseAvatarConfig provides the following properties:
Property | Description |
---|---|
avatarShape | The avatar style: default style, round, and rectangular. |
avatarRadius | The border radius of the avatar. This property is valid only for a rectangular avatar. |
avatarBorderColor | The color of the avatar frame. |
avatarBorderWidth | The width of the avatar frame. |
EaseChatConfig provides the following properties:
Property | Description |
---|---|
enableReplyMessage | Whether to enable the message reply function: - (Default) true: Yes - false: No |
enableModifyMessageAfterSent | Whether to enable the message edit function: - (Default) true: Yes - false: No |
timePeriodCanRecallMessage | The message recall duration, which is 2 minutes by default. |
EaseDateFormatConfig provides the following properties:
Property | Description |
---|---|
convTodayFormat | The date format of the current day on the conversation list. The default format is "HH:mm" in the English context. |
convOtherDayFormat | The date format of other dates than of the current day on the conversation list. The default format is "HH:mm" in the English context. |
convOtherYearFormat | The date format of other years than this year on the conversation list. The default format is "MMM dd, yyyy" in the English context. |
EaseSystemMsgConfig provides the following property:
Property | Description |
---|---|
useDefaultContactInvitedSystemMsg | Whether to enable the system message function: (Default) - true: Yes - false: No |
EaseMultiDeviceEventConfig provides the following properties:
Property | Description |
---|---|
useDefaultMultiDeviceContactEvent | Whether to enable the default multi-device contact event processing: (Default) - true: Yes - false: No |
useDefaultMultiDeviceGroupEvent | Whether to enable the default multi-device group event processing: (Default) - true: Yes - false: No |
User information is used in many places in UIKit and needs to be provided by developers. This section describes how developers provide user information to UIKit.
During a call to the login API EaseIM.login
, the user needs to pass in an EaseProfile
object. This object contains the following attributes:
id
: The user ID. This parameter is required.name
andavatar
: Used to display the nickname and avatar of the current user. When sending a message, you can set the two parameters to theext
field of the message to allow other users to present the two parameters. If you fail to pass in the two parameters during login, you can callEaseIM.updateCurrentUser
to update the current user's information after login.
UIKit provides EaseIM.setUserProfileProvider
to provide user information.
EaseUserProfileProvider
API is as follows:
interface EaseUserProfileProvider {
// Gets user information synchronously
fun getUser(userId: String?): EaseProfile?
// Gets user information asynchronously
fun fetchUsers(userIds: List<String>, onValueSuccess: OnValueSuccess<List<EaseProfile>>)
}
This API is used as follows:
EaseIM.setUserProfileProvider(object : EaseUserProfileProvider {
// Gets user information synchronously
override fun getUser(userId: String?): EaseProfile? {
return getLocalUserInfo(userId)
}
override fun fetchUsers(
userIds: List<String>,
onValueSuccess: OnValueSuccess<List<EaseProfile>>
) {
fetchUserInfoFromServer(idsMap, onValueSuccess)
}
})
UIKit provides the EaseIM.setGroupProfileProvider
to provide the user information.
EaseGroupProfileProvider
is as follows:
interface EaseGroupProfileProvider {
// Gets user information synchronously
fun getGroup(userId: String?): EaseGroupProfile?
// Gets user information asynchronously
fun fetchGroups(userIds: List<String>, onValueSuccess: OnValueSuccess<List<EaseGroupProfile>>)
}
This API is used as follows:
EaseIM.setGroupProfileProvider(object : EaseGroupProfileProvider {
// Gets group information synchronously
override fun getGroup(groupId: String?): EaseGroupProfile? {
ChatClient.getInstance().groupManager().getGroup(id)?.let {
return EaseGroupProfile(it.groupId, it.groupName, it.extension)
}
return null
}
override fun fetchGroups(
groupIds: List<String>,
onValueSuccess: OnValueSuccess<List<EaseGroupProfile>>
) {
}
})
- Step 1: If the information has been cached in the memory, when information needs to be presented on pages, the UIKit will first retrieve the cached data from the memory and render the page. If no information is cached, proceed to step 2.
- Step 2. UIKit calls the provider synchronization method to obtain information locally from the application. Developers can obtain and provide the related information from the application's local database or memory. After the information is obtained, UIKit renders the page, while caching the information.
- Step 3. If the data obtained by the synchronization method is empty, when the list page stops sliding, UIKit will return the information required for the items visible on the current page through the asynchronous method provided by the provider after excluding cache and data provided by the synchronization method. After obtaining the corresponding information from the server, the developer provides it to UIKit through
onValueSuccess
. The UIKit refreshes the list and updates the corresponding data when receiving the data.
As information is cached in the UIKit, the UIKit will update the cached information via the update
methods if the user information is changed.
// First call EaseIM.getCache().getUser | EaseIM.getCache().getGroup to get the local cached object, and then call the update methods:
// Updates current user information user: EaseProfile
EaseIM.updateCurrentUser(user)
// Updates user information in batches list: List<EaseProfile>
EaseIM.updateUsersInfo(list)
// Updates group information in batches groups: List<EaseGroupProfile>
EaseIM.updateGroupInfo(groups)
UIKit supports both light and dark themes, with the theme colors changing with the system theme. To adjust the theme colors, you can create a new values-night
folder in the app module, copy ease_colors.xml
to this folder, and then modify the basic colors in it. Under the dark theme, the corresponding colors will also be changed.