CometChatUsers renders a scrollable list of all available users with real-time presence updates, search, avatars, and online/offline status indicators.
Where It Fits
CometChatUsers is a list component. It renders all available users and emits the selected User via onItemClick. Wire it to CometChatMessageHeader, CometChatMessageList, and CometChatMessageComposer to build a direct messaging layout.
Kotlin (XML Views)
Jetpack Compose
< com.cometchat.uikit.kotlin.presentation.users.ui.CometChatUsers
android:id = "@+id/users"
android:layout_width = "match_parent"
android:layout_height = "match_parent" />
val users = findViewById < CometChatUsers >(R.id.users)
users. setOnItemClick { user ->
messageHeader. setUser (user)
messageList. setUser (user)
messageComposer. setUser (user)
}
CometChatUsers (
modifier = Modifier. fillMaxSize (),
onItemClick = { user ->
messageHeader. setUser (user)
messageList. setUser (user)
messageComposer. setUser (user)
}
)
Quick Start
Kotlin (XML Views)
Jetpack Compose
Add to your layout XML: < com.cometchat.uikit.kotlin.presentation.users.ui.CometChatUsers
android:id = "@+id/users"
android:layout_width = "match_parent"
android:layout_height = "match_parent" />
Or programmatically: override fun onCreate (savedInstanceState: Bundle ?) {
super . onCreate (savedInstanceState)
setContentView ( CometChatUsers ( this ))
}
@Composable
fun UsersScreen () {
CometChatUsers (
modifier = Modifier. fillMaxSize ()
)
}
Prerequisites: CometChat SDK initialized with CometChatUIKit.init(), a user logged in, and the UI Kit dependency added.
Or in a Fragment:
Kotlin (XML Views)
Jetpack Compose
override fun onCreateView (inflater: LayoutInflater , container: ViewGroup ?, savedInstanceState: Bundle ?): View {
return CometChatUsers ( requireContext ())
}
override fun onCreateView (inflater: LayoutInflater , container: ViewGroup ?, savedInstanceState: Bundle ?): View {
return ComposeView ( requireContext ()). apply {
setContent { CometChatUsers () }
}
}
Filtering Users
Kotlin (XML Views)
Jetpack Compose
Pass a UsersRequest.UsersRequestBuilder to control what loads: users. setUsersRequestBuilder (
UsersRequest. UsersRequestBuilder ()
. friendsOnly ( true )
. setLimit ( 20 )
)
CometChatUsers (
usersRequestBuilder = UsersRequest. UsersRequestBuilder ()
. friendsOnly ( true )
. setLimit ( 20 )
)
Filter Recipes
Recipe Builder method Friends only .friendsOnly(true)Limit per page .setLimit(10)Search by keyword .setSearchKeyword("john")Hide blocked users .hideBlockedUsers(true)Filter by roles .setRoles(listOf("admin", "moderator"))Filter by tags .setTags(listOf("vip"))Online users only .setUserStatus(CometChatConstants.USER_STATUS_ONLINE)Filter by UIDs .setUIDs(listOf("uid1", "uid2"))
Pass the builder object, not the result of .build(). The component calls .build() internally. Default page size is 30 with infinite scroll.
Actions and Events
Callback Methods
onItemClick
Fires when a user row is tapped. Primary navigation hook.
Kotlin (XML Views)
Jetpack Compose
users. setOnItemClick { user ->
// Navigate to chat screen
}
CometChatUsers (
onItemClick = { user ->
// Navigate to chat screen
}
)
Replaces the default item-click behavior. Your custom lambda executes instead of the built-in navigation.
onItemLongClick
Fires when a user row is long-pressed. Use for additional actions like block or mute.
Kotlin (XML Views)
Jetpack Compose
users. setOnItemLongClick { user ->
// Show context menu
}
CometChatUsers (
onItemLongClick = { user ->
// Show context menu
}
)
onBackPress
Fires when the user presses the back button in the toolbar.
Kotlin (XML Views)
Jetpack Compose
users. setOnBackPress {
finish ()
}
CometChatUsers (
onBackPress = { /* navigate back */ }
)
onSearchClick
Fires when the user taps the search icon in the toolbar.
Kotlin (XML Views)
Jetpack Compose
users. setOnSearchClick {
// Open search screen
}
CometChatUsers (
onSearchClick = { /* open search */ }
)
onSelection
Fires when users are selected/deselected in multi-select mode.
Kotlin (XML Views)
Jetpack Compose
users. setSelectionMode (UIKitConstants.SelectionMode.MULTIPLE)
users. setOnSelection { selectedUsers ->
updateToolbar (selectedUsers.size)
}
CometChatUsers (
selectionMode = UIKitConstants.SelectionMode.MULTIPLE,
onSelection = { selectedUsers ->
updateToolbar (selectedUsers.size)
}
)
onError
Fires on internal errors (network failure, auth issue, SDK exception).
Kotlin (XML Views)
Jetpack Compose
users. setOnError { exception ->
Log. e ( "Users" , "Error: ${ exception.message } " )
}
CometChatUsers (
onError = { exception ->
Log. e ( "Users" , "Error: ${ exception.message } " )
}
)
onLoad
Fires when the list is successfully fetched and loaded.
Kotlin (XML Views)
Jetpack Compose
users. setOnLoad { userList ->
Log. d ( "Users" , "Loaded ${ userList.size } " )
}
CometChatUsers (
onLoad = { userList ->
Log. d ( "Users" , "Loaded ${ userList.size } " )
}
)
onEmpty
Fires when the list is empty after loading.
Kotlin (XML Views)
Jetpack Compose
users. setOnEmpty {
Log. d ( "Users" , "No users found" )
}
CometChatUsers (
onEmpty = { /* no users */ }
)
SDK Events (Real-Time, Automatic)
The component listens to these SDK events internally. No manual setup needed.
SDK Listener Internal behavior onUserOnlineUpdates online status indicator for the user onUserOfflineUpdates offline status indicator for the user
Functionality
Method (Kotlin XML) Compose Parameter Description setBackIconVisibility(View.VISIBLE)hideBackIcon = falseToggle back button setToolbarVisibility(View.GONE)hideToolbar = trueToggle toolbar setSearchBoxVisibility(View.GONE)hideSearchBox = trueToggle search box setStickyHeaderVisibility(View.GONE)hideStickyHeader = trueToggle alphabetical sticky header setUserStatusVisibility(View.GONE)hideUserStatus = trueToggle online status indicator setSeparatorVisibility(View.GONE)hideSeparator = trueToggle list separators setSelectionMode(MULTIPLE)selectionMode = MULTIPLEEnable selection mode setTitle("Contacts")title = "Contacts"Custom toolbar title setSearchPlaceholderText("Find...")searchPlaceholderText = "Find..."Search placeholder
Custom View Slots
Leading View
Replace the avatar / left section.
Kotlin (XML Views)
Jetpack Compose
users. setLeadingView ( object : UsersViewHolderListener () {
override fun createView (context: Context , binding: CometchatListBaseItemsBinding ): View {
return ImageView (context). apply {
layoutParams = ViewGroup. LayoutParams ( 48 .dp, 48 .dp)
}
}
override fun bindView (
context: Context , createdView: View , user: User ,
holder: RecyclerView .ViewHolder, userList: List < User >, position: Int
) {
val imageView = createdView as ImageView
// Load avatar image
}
})
CometChatUsers (
leadingView = { user ->
CometChatAvatar (
imageUrl = user.avatar,
name = user.name
)
}
)
Title View
Replace the name / title text.
Kotlin (XML Views)
Jetpack Compose
users. setTitleView ( object : UsersViewHolderListener () {
override fun createView (context: Context , binding: CometchatListBaseItemsBinding ): View {
return TextView (context)
}
override fun bindView (
context: Context , createdView: View , user: User ,
holder: RecyclerView .ViewHolder, userList: List < User >, position: Int
) {
(createdView as TextView).text = user.name ?: ""
}
})
CometChatUsers (
titleView = { user ->
Text (
text = user.name ?: "" ,
style = CometChatTheme.typography.heading4Medium
)
}
)
Subtitle View
Replace the subtitle text below the user’s name.
Kotlin (XML Views)
Jetpack Compose
users. setSubtitleView ( object : UsersViewHolderListener () {
override fun createView (context: Context , binding: CometchatListBaseItemsBinding ): View {
return TextView (context)
}
override fun bindView (
context: Context , createdView: View , user: User ,
holder: RecyclerView .ViewHolder, userList: List < User >, position: Int
) {
val tvSubtitle = createdView as TextView
tvSubtitle.text = "Last Active: " + SimpleDateFormat ( "dd/MM/yyyy, HH:mm:ss" ). format (user.lastActiveAt * 1000 )
}
})
CometChatUsers (
subtitleView = { user ->
Text (
text = "Last Active: ${ SimpleDateFormat ( "dd/MM/yyyy" ). format (user.lastActiveAt * 1000 ) } " ,
maxLines = 1 ,
overflow = TextOverflow.Ellipsis
)
}
)
Trailing View
Replace the right section of each user item.
Kotlin (XML Views)
Jetpack Compose
users. setTrailingView ( object : UsersViewHolderListener () {
override fun createView (context: Context , binding: CometchatListBaseItemsBinding ): View {
return TextView (context)
}
override fun bindView (
context: Context , createdView: View , user: User ,
holder: RecyclerView .ViewHolder, userList: List < User >, position: Int
) {
(createdView as TextView).text = user.role ?: ""
}
})
CometChatUsers (
trailingView = { user ->
Text (text = user.role ?: "" )
}
)
Item View
Replace the entire list item row.
Kotlin (XML Views)
Jetpack Compose
users. setItemView ( object : UsersViewHolderListener () {
override fun createView (context: Context , binding: CometchatListBaseItemsBinding ): View {
return LayoutInflater. from (context). inflate (R.layout.custom_user_item, null )
}
override fun bindView (
context: Context , createdView: View , user: User ,
holder: RecyclerView .ViewHolder, userList: List < User >, position: Int
) {
val avatar = createdView. findViewById < CometChatAvatar >(R.id.custom_avatar)
val title = createdView. findViewById < TextView >(R.id.tvName)
title.text = user.name
avatar. setAvatar (user.name, user.avatar)
}
})
CometChatUsers (
itemView = { user ->
Row (
modifier = Modifier. fillMaxWidth (). padding ( 12 .dp),
verticalAlignment = Alignment.CenterVertically
) {
CometChatAvatar (imageUrl = user.avatar, name = user.name)
Spacer (Modifier. width ( 12 .dp))
Text (user.name ?: "" , style = CometChatTheme.typography.heading4Medium)
}
}
)
State Views
Kotlin (XML Views)
Jetpack Compose
users. setEmptyView (R.layout.custom_empty_view)
users. setErrorView (R.layout.custom_error_view)
users. setLoadingView (R.layout.custom_loading_view)
CometChatUsers (
emptyView = { Text ( "No users found" ) },
errorView = { onRetry -> Button (onClick = onRetry) { Text ( "Retry" ) } },
loadingView = { CircularProgressIndicator () }
)
Kotlin (XML Views)
Jetpack Compose
users. setOverflowMenu ( ImageButton (context). apply {
setImageResource (R.drawable.ic_filter)
setOnClickListener { /* show filter */ }
})
CometChatUsers (
overflowMenu = {
IconButton (onClick = { /* show filter */ }) {
Icon ( painterResource (R.drawable.ic_filter), "Filter" )
}
}
)
Kotlin (XML Views)
Jetpack Compose
// Replace all options
users. setOptions { context, user ->
listOf (
CometChatPopupMenu. MenuItem (id = "block" , name = "Block" , onClick = { /* ... */ }),
CometChatPopupMenu. MenuItem (id = "mute" , name = "Mute" , onClick = { /* ... */ })
)
}
// Append to defaults
users. setAddOptions { context, user ->
listOf (
CometChatPopupMenu. MenuItem (id = "pin" , name = "Pin" , onClick = { /* ... */ })
)
}
CometChatUsers (
options = { context, user ->
listOf (
MenuItem (id = "block" , name = "Block" , onClick = { /* ... */ }),
MenuItem (id = "mute" , name = "Mute" , onClick = { /* ... */ })
)
},
addOptions = { context, user ->
listOf ( MenuItem (id = "pin" , name = "Pin" , onClick = { /* ... */ }))
}
)
Common Patterns
Minimal list — hide all chrome
Kotlin (XML Views)
Jetpack Compose
users. setToolbarVisibility (View.GONE)
users. setSearchBoxVisibility (View.GONE)
users. setStickyHeaderVisibility (View.GONE)
users. setUserStatusVisibility (View.GONE)
CometChatUsers (
hideToolbar = true ,
hideSearchBox = true ,
hideStickyHeader = true ,
hideUserStatus = true
)
Friends-only list
Kotlin (XML Views)
Jetpack Compose
users. setUsersRequestBuilder (
UsersRequest. UsersRequestBuilder ()
. friendsOnly ( true )
)
CometChatUsers (
usersRequestBuilder = UsersRequest. UsersRequestBuilder ()
. friendsOnly ( true )
)
Online users only
Kotlin (XML Views)
Jetpack Compose
users. setUsersRequestBuilder (
UsersRequest. UsersRequestBuilder ()
. setUserStatus (CometChatConstants.USER_STATUS_ONLINE)
)
CometChatUsers (
usersRequestBuilder = UsersRequest. UsersRequestBuilder ()
. setUserStatus (CometChatConstants.USER_STATUS_ONLINE)
)
Advanced Methods
Programmatic Selection
Kotlin (XML Views)
Jetpack Compose
// Enable selection
users. setSelectionMode (UIKitConstants.SelectionMode.MULTIPLE)
// Select a user
users. selectUser (user, UIKitConstants.SelectionMode.MULTIPLE)
// Get selected
val selected = users. getSelectedUsers ()
// Clear
users. clearSelection ()
Selection is managed via the selectionMode and onSelection parameters. The component handles selection state internally.
ViewModel Access
val factory = CometChatUsersViewModelFactory ()
val viewModel = ViewModelProvider ( this , factory)
. get (CometChatUsersViewModel:: class .java)
Kotlin (XML Views)
Jetpack Compose
users. setViewModel (viewModel)
CometChatUsers (
usersViewModel = viewModel
)
See ViewModel & Data for ListOperations, state observation, and custom repositories.
Style
Kotlin (XML Views)
Jetpack Compose
Define a custom style in themes.xml: < style name = "CustomAvatarStyle" parent = "CometChatAvatarStyle" >
< item name = "cometchatAvatarStrokeRadius" > 8dp </ item >
< item name = "cometchatAvatarBackgroundColor" > #FBAA75 </ item >
</ style >
< style name = "CustomUsersStyle" parent = "CometChatUsersStyle" >
< item name = "cometchatUsersAvatarStyle" > @style/CustomAvatarStyle </ item >
< item name = "cometchatUsersSeparatorColor" > #F76808 </ item >
< item name = "cometchatUsersTitleTextColor" > #F76808 </ item >
</ style >
< style name = "AppTheme" parent = "CometChatTheme.DayNight" >
< item name = "cometchatUsersStyle" > @style/CustomUsersStyle </ item >
</ style >
CometChatUsers (
style = CometChatUsersStyle. default (). copy (
backgroundColor = Color ( 0xFFF5F5F5 ),
titleTextColor = Color ( 0xFF141414 ),
itemStyle = CometChatUsersItemStyle. default (). copy (
backgroundColor = Color.White,
titleTextColor = Color ( 0xFF141414 ),
subtitleTextColor = Color ( 0xFF727272 ),
avatarStyle = CometChatAvatarStyle. default (). copy (cornerRadius = 12 .dp),
statusIndicatorStyle = CometChatStatusIndicatorStyle. default (). copy ()
)
)
)
Style Properties
Property Description backgroundColorList background color titleTextColorToolbar title color searchBoxStyleSearch box appearance itemStyle.backgroundColorRow background itemStyle.selectedBackgroundColorSelected row background itemStyle.titleTextColorUser name color itemStyle.subtitleTextColorSubtitle text color itemStyle.separatorColorRow separator color itemStyle.avatarStyleAvatar appearance itemStyle.statusIndicatorStyleOnline/offline indicator
See Component Styling for the full reference.
Next Steps
Conversations Browse recent conversations
Groups Browse and search available groups
Component Styling Detailed styling reference with screenshots
ViewModel & Data Custom ViewModels, repositories, and ListOperations