Feedback

Android(Compose)

组件概述

ContactList 是基于 Jetpack Compose 构建的联系人列表组件,为用户提供完整的联系人管理功能。该组件支持好友列表展示与搜索、好友申请处理、入群申请处理、群组列表、黑名单管理,以及添加好友、加入群聊、发起单聊、创建群聊等流程,并支持自定义列表顶部的入口。
联系人列表
群组列表
好友申请列表




组件集成

ContactList 组件属于 TUIKit Compose 的一部分,集成 TUIKit Compose 即可获取并使用 ContactList 组件。集成方法请参考文档 TUIKit Compose 里的集成步骤。

组件构成

ContactList 是联系人列表里的主组件,对应着整个联系人列表页框架:
方法名
参数
描述
ContactList
modifier: Modifier
Jetpack Compose 中用来设置组件的样式、布局、行为和外观。
config: ContactListConfigProtocol
联系人列表配置,控制顶部入口和搜索栏的显示,并支持编辑顶部入口。默认值为 ChatContactListConfig()。
onGroupClick: (ContactInfo) -> Unit
点击“我的群聊”中的群组时的回调,ContactInfo 的 userID 为群 ID。可选参数。
onContactClick: (ContactInfo) -> Unit
点击好友列表或黑名单中的用户时的回调。可选参数。
contactListViewModelFactory: ContactListViewModelFactory
创建组件内部 ContactListViewModel 的工厂类。通常情况下,您无需手动创建,组件已提供默认实现。
onCreateChat: (String) -> Unit
通过 flowController 发起单聊或创建群聊完成后的回调,参数为对应会话的会话 ID。可选参数。
flowController: ContactListFlowController
流程控制器,可以在外部打开添加好友、加入群聊、发起单聊、创建群聊等页面,详见下方“流程控制”。默认由组件内部创建。
ContactList 顶部为搜索栏和各个子页面的入口,默认依次为“新的联系人”(好友申请)、“群聊通知”(入群申请)、“我的群聊”和“黑名单”,前两个入口会以角标展示未读的申请数量。下方为按首字母排序的好友列表,在搜索栏中输入关键字可以筛选好友,此时顶部入口会隐藏。

基础用法

在 ContactList 中点击“新的联系人”“群聊通知”“我的群聊”“黑名单”入口时,组件会自动打开对应的页面,无需额外处理;点击“我的群聊”中的群组,或者好友列表、黑名单中的用户时,会触发相应的回调接口(onGroupClick / onContactClick),需监听回调并实现自定义跳转。
初始化 ContactList 即可直接展示联系人列表,示例代码如下:
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.systemBarsPadding
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import io.trtc.tuikit.chat.uikit.components.contactlist.ui.ContactList

@Composable
fun ContactListScreen(
onOpenChat: (conversationID: String) -> Unit,
onOpenUserProfile: (userID: String) -> Unit
) {
Box(
modifier = Modifier
.fillMaxSize()
.systemBarsPadding()
) {
ContactList(
onGroupClick = { group ->
// 点击“我的群聊”中的群组,group.userID 为群 ID
onOpenChat("group_${group.userID}")
},
onContactClick = { contact ->
// 点击好友列表或黑名单中的用户
onOpenUserProfile(contact.userID)
}
)
}
}

自定义组件

您可以隐藏或编辑联系人列表顶部的入口,也可以在外部打开添加好友、发起聊天等流程。方法如下。

隐藏入口和搜索栏

通过 ChatContactListConfig 中的开关控制顶部入口和搜索栏是否显示,所有开关的默认值均为 true。您也可以自行实现 ContactListConfigProtocol 接口来提供配置。
开关
对应入口 ID
描述
showNewContacts
ContactListItemIDs.NEW_CONTACTS
“新的联系人”入口,进入后可以处理好友申请。
showGroupApplications
ContactListItemIDs.GROUP_APPLICATIONS
“群聊通知”入口,进入后可以处理入群申请。
showMyGroups
ContactListItemIDs.MY_GROUPS
“我的群聊”入口。
showBlacklist
ContactListItemIDs.BLACKLIST
“黑名单”入口。
showSearchBar
无
顶部的好友搜索栏。
示例代码如下:
import io.trtc.tuikit.chat.uikit.components.contactlist.config.ChatContactListConfig
import io.trtc.tuikit.chat.uikit.components.contactlist.ui.ContactList

ContactList(
config = ChatContactListConfig(
showGroupApplications = false, // 隐藏“群聊通知”
showBlacklist = false, // 隐藏“黑名单”
showSearchBar = false // 隐藏搜索栏
),
onContactClick = { contact ->
// 点击联系人
}
)

编辑入口

如需替换、移动或新增顶部入口,可以通过 ChatContactListConfig 的 customizeItems 编辑入口。在 customizeItems 中,可以通过 editorContext.androidContext 获取 Android Context,并调用以下方法编辑入口:
方法
描述
add(item)
在末尾添加入口。item 的 ID 为空白或与已有入口重复时会抛出 IllegalArgumentException。
remove(ID)
移除指定 ID 的入口,不存在时返回 false。
replace(ID) { item -> ... }
替换指定 ID 的入口,不存在时返回 false。替换后的入口必须保持 ID 不变,否则会抛出异常。
insertBefore(anchorID, item) / insertAfter(anchorID, item)
在锚点入口之前或之后插入入口。锚点不存在时返回 false,且不会插入。item 的 ID 规则与 add 相同。
moveBefore(ID, anchorID) / moveAfter(ID, anchorID)
将入口移动到锚点入口之前或之后,任意一个 ID 不存在时返回 false。
clear()
移除全部入口。
items
当前入口列表的只读快照。
入口 ContactCustomItem 的字段说明如下:
字段
类型
描述
ID
String
入口的唯一标识,必填。
title
String
入口标题,不为空时优先使用。
titleResID
Int
入口标题的字符串资源 ID,title 为空时使用。
iconResID
Int
入口图标的 drawable 资源 ID,以 40dp 大小显示,不会着色;为 0 时不显示图标。
badgeCount
StateFlow<Int>
角标数量,大于 0 时显示,超过 99 时显示为 99+。默认为 0。
onClick
() -> Unit
点击入口时的回调。
示例代码如下:
import io.trtc.tuikit.chat.uikit.components.contactlist.config.ChatContactListConfig
import io.trtc.tuikit.chat.uikit.components.contactlist.model.ContactCustomItem
import io.trtc.tuikit.chat.uikit.components.contactlist.model.ContactListItemIDs
import io.trtc.tuikit.chat.uikit.components.contactlist.ui.ContactList
import kotlinx.coroutines.flow.MutableStateFlow

// “标签”入口的角标数量,业务侧更新 value 后角标会自动刷新
val tagBadgeCount = MutableStateFlow(0)

val contactListConfig = ChatContactListConfig().customizeItems {
// 修改“新的联系人”的标题
replace(ContactListItemIDs.NEW_CONTACTS) { item ->
item.copy(title = "好友申请")
}
// 在“我的群聊”之后插入“标签”入口
insertAfter(
ContactListItemIDs.MY_GROUPS,
ContactCustomItem(
ID = "custom.contactList.tags",
title = "标签",
iconResID = android.R.drawable.ic_menu_agenda,
badgeCount = tagBadgeCount,
onClick = {
// 跳转到标签页面
}
)
)
}

ContactList(config = contactListConfig)
注意:
顶部入口列表会根据配置缓存,只在配置变化时重新生成,因此请通过 badgeCount 的 StateFlow 动态更新角标。建议将配置对象定义为常量或通过 remember 保存,避免每次重组都创建新的配置。

流程控制

通过 rememberContactListFlowController() 创建 ContactListFlowController 并传给 ContactList 的 flowController 参数后,可以在外部打开以下页面,例如在页面右上角的“+”菜单中调用:
方法/属性
描述
showAddFriendPage()
打开添加好友页面。
showAddGroupPage()
打开加入群聊页面。
showStartSingleChatPage()
打开发起单聊页面,选择好友后会回调 onCreateChat。
showCreateGroupChatPage()
打开创建群聊页面,创建成功后会回调 onCreateChat。
showAddFriendForContact(contactInfo)
打开添加好友页面,并直接展示指定用户的资料。
dismiss()
关闭当前打开的页面。
currentFlow: ContactListFlow?
当前打开的页面类型,未打开页面时为 null。
示例代码如下:
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import io.trtc.tuikit.chat.uikit.components.contactlist.ui.ContactList
import io.trtc.tuikit.chat.uikit.components.contactlist.ui.rememberContactListFlowController

@Composable
fun ContactsScreen(onOpenChat: (conversationID: String) -> Unit) {
val flowController = rememberContactListFlowController()
Column(modifier = Modifier.fillMaxSize()) {
Row(
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 16.dp, vertical = 12.dp),
horizontalArrangement = Arrangement.spacedBy(16.dp)
) {
Text(text = "添加好友", modifier = Modifier.clickable { flowController.showAddFriendPage() })
Text(text = "添加群聊", modifier = Modifier.clickable { flowController.showAddGroupPage() })
Text(text = "发起单聊", modifier = Modifier.clickable { flowController.showStartSingleChatPage() })
Text(text = "创建群聊", modifier = Modifier.clickable { flowController.showCreateGroupChatPage() })
}
ContactList(
modifier = Modifier.weight(1f),
flowController = flowController,
onCreateChat = { conversationID ->
// 发起单聊或创建群聊完成,跳转到对应的聊天页面
onOpenChat(conversationID)
}
)
}
}
如果页面中没有使用 ContactList,也可以通过 ContactListFlowHost(controller = flowController, onCreateChat = { ... }) 单独承载这些页面。