Skip to main content
{
  "component": "CometChatUsers",
  "package": "com.cometchat.chatuikit.users",
  "xmlElement": "<com.cometchat.chatuikit.users.CometChatUsers />",
  "description": "Scrollable list of all available users with search, avatars, names, and online/offline status indicators.",
  "primaryOutput": {
    "method": "setOnItemClick",
    "type": "OnItemClick<User>"
  },
  "methods": {
    "data": {
      "setUsersRequestBuilder": {
        "type": "UsersRequest.UsersRequestBuilder",
        "default": "SDK default",
        "note": "Pass the builder, not the result of .build()"
      },
      "setSearchRequestBuilder": {
        "type": "UsersRequest.UsersRequestBuilder",
        "default": "Same as main builder",
        "note": "Separate builder for search results"
      }
    },
    "callbacks": {
      "setOnItemClick": "OnItemClick<User>",
      "setOnItemLongClick": "OnItemLongClick<User>",
      "setOnBackPressListener": "OnBackPress",
      "setOnSelect": "OnSelection<User>",
      "setOnError": "OnError",
      "setOnLoad": "OnLoad<User>",
      "setOnEmpty": "OnEmpty"
    },
    "visibility": {
      "setBackIconVisibility": { "type": "int (View.VISIBLE | View.GONE)", "default": "View.GONE" },
      "setToolbarVisibility": { "type": "int", "default": "View.VISIBLE" },
      "setLoadingStateVisibility": { "type": "int", "default": "View.VISIBLE" },
      "setErrorStateVisibility": { "type": "int", "default": "View.VISIBLE" },
      "setEmptyStateVisibility": { "type": "int", "default": "View.VISIBLE" },
      "setSeparatorVisibility": { "type": "int", "default": "View.VISIBLE" },
      "setUserStatusVisibility": { "type": "int", "default": "View.VISIBLE" },
      "setStickyHeaderVisibility": { "type": "int", "default": "View.VISIBLE" },
      "setSearchBoxVisibility": { "type": "int", "default": "View.VISIBLE" }
    },
    "selection": {
      "setSelectionMode": {
        "type": "UIKitConstants.SelectionMode",
        "values": ["NONE", "SINGLE", "MULTIPLE"],
        "default": "NONE"
      }
    },
    "viewSlots": {
      "seItemView": "UsersViewHolderListener — entire list item row (note: typo in SDK method name)",
      "setLeadingView": "UsersViewHolderListener — avatar / left section",
      "setTitleView": "UsersViewHolderListener — name / title text",
      "setSubtitleView": "UsersViewHolderListener — subtitle text below name",
      "setTrailingView": "UsersViewHolderListener — right section",
      "setLoadingView": "@LayoutRes int — loading spinner",
      "setEmptyView": "@LayoutRes int — empty state",
      "setErrorView": "@LayoutRes int — error state",
      "setOverflowMenu": "View — toolbar menu",
      "setOptions": "Function2<Context, User, List<MenuItem>> — long-press context menu (replaces defaults)",
      "addOptions": "Function2<Context, User, List<MenuItem>> — long-press context menu (appends to defaults)"
    },
    "advanced": {
      "selectUser": "User, SelectionMode — programmatic selection",
      "clearSelection": "void — clears all selected users",
      "getSelectedUsers": "List<User> — returns selected items",
      "setSearchKeyword": "String — programmatic search",
      "setTitleText": "String — custom toolbar title",
      "setSearchPlaceholderText": "String — search placeholder",
      "getBinding": "CometchatUserListBinding — root ViewBinding",
      "getViewModel": "UsersViewModel — internal ViewModel access",
      "getUsersAdapter": "UsersAdapter — internal adapter access",
      "setAdapter": "UsersAdapter — replace the default adapter"
    },
    "style": {
      "setStyle": {
        "type": "@StyleRes int",
        "parent": "CometChatUsersStyle"
      }
    }
  },
  "events": [
    {
      "name": "CometChatUserEvents.ccUserBlocked",
      "payload": "User",
      "description": "Logged-in user blocked another user"
    },
    {
      "name": "CometChatUserEvents.ccUserUnblocked",
      "payload": "User",
      "description": "Logged-in user unblocked another user"
    }
  ],
  "sdkListeners": [
    "onUserOnline",
    "onUserOffline"
  ]
}

Where It Fits

CometChatUsers is a list component. It renders all available users and emits the selected User via setOnItemClick. Wire it to CometChatMessageHeader, CometChatMessageList, and CometChatMessageComposer to build a direct messaging layout.
ChatActivity.kt
class ChatActivity : AppCompatActivity() {

    private lateinit var users: CometChatUsers
    private lateinit var messageHeader: CometChatMessageHeader
    private lateinit var messageList: CometChatMessageList
    private lateinit var messageComposer: CometChatMessageComposer

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_chat)

        users = findViewById(R.id.users)
        messageHeader = findViewById(R.id.message_header)
        messageList = findViewById(R.id.message_list)
        messageComposer = findViewById(R.id.message_composer)

        users.setOnItemClick { view, position, user ->
            messageHeader.setUser(user)
            messageList.setUser(user)
            messageComposer.setUser(user)
        }
    }
}

Quick Start

Add the component to your layout XML:
layout_activity.xml
<com.cometchat.chatuikit.users.CometChatUsers
        android:id="@+id/users"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
Prerequisites: CometChat SDK initialized with CometChatUIKit.init(), a user logged in, and the cometchat-chat-uikit-android dependency added. To add programmatically in an Activity:
YourActivity.kt
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(CometChatUsers(this))
}
Or in a Fragment:
YourFragment.kt
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
    return CometChatUsers(requireContext())
}

Filtering Users

Pass a UsersRequest.UsersRequestBuilder to setUsersRequestBuilder. Pass the builder instance — not the result of .build().
val builder = UsersRequest.UsersRequestBuilder()
    .friendsOnly(false)
    .setLimit(10)
cometChatUsers.setUsersRequestBuilder(builder)

Filter Recipes

RecipeCode
Friends onlybuilder.friendsOnly(true)
Limit to 10 per pagebuilder.setLimit(10)
Search by keywordbuilder.setSearchKeyword("john")
Hide blocked usersbuilder.hideBlockedUsers(true)
Filter by rolesbuilder.setRoles(Arrays.asList("admin", "moderator"))
Filter by tagsbuilder.setTags(Arrays.asList("vip"))
Online users onlybuilder.setUserStatus(CometChatConstants.USER_STATUS_ONLINE)
Filter by UIDsbuilder.setUIDs(Arrays.asList("uid1", "uid2"))
The component uses infinite scroll — the next page loads as the user scrolls to the bottom. Refer to UsersRequestBuilder for the full builder API.

Search Request Builder

Use setSearchRequestBuilder to customize the search list separately from the main list:
val searchBuilder = UsersRequest.UsersRequestBuilder()
    .setSearchKeyword("**")
cometChatUsers.setSearchRequestBuilder(searchBuilder)

Actions and Events

Callback Methods

setOnItemClick

Fires when a user row is tapped. Primary navigation hook — set the active user and render the message view.
YourActivity.kt
cometchatUsers.onItemClick = OnItemClick { view, position, user ->
            
}
What this does: Replaces the default item-click behavior. When a user taps a user item, your custom lambda executes instead of the built-in navigation.

setOnItemLongClick

Fires when a user row is long-pressed. Use for additional actions like block or mute.
YourActivity.kt
cometchatUsers.onItemLongClick = OnItemLongClick({ view, position, user ->
            
})

setOnBackPressListener

Fires when the user presses the back button in the app bar. Default: navigates to the previous activity.
YourActivity.kt
cometchatUsers.onBackPressListener = OnBackPress {

}

setOnSelect

Fires when a user is checked/unchecked in multi-select mode. Requires setSelectionMode to be set.
YourActivity.kt
cometchatUsers.setOnSelect(object : OnSelection<User?> {
    override fun onSelection(t: MutableList<User?>?) {
                
    }
})

setOnError

Fires on internal errors (network failure, auth issue, SDK exception).
YourActivity.kt
cometchatUsers.setOnError {

}

setOnLoad

Fires when the list is successfully fetched and loaded.
YourActivity.kt
cometchatUsers.setOnLoad(object : OnLoad<User?> {
    override fun onLoad(list: MutableList<User?>?) {

    }
})

setOnEmpty

Fires when the list is empty, enabling custom handling such as showing a placeholder.
YourActivity.kt
cometchatUsers.setOnEmpty {
            
}
  • Verify: After setting an action callback, trigger the corresponding user interaction (tap, long-press, back, select) and confirm your custom logic executes instead of the default behavior.

Global UI Events

CometChatUserEvents emits events subscribable from anywhere in the application. Add a listener and remove it when no longer needed.
EventFires whenPayload
ccUserBlockedThe logged-in user blocks another userUser
ccUserUnblockedThe logged-in user unblocks another userUser
Add Listener
CometChatUserEvents.addUserListener("LISTENER_TAG", object : CometChatUserEvents() {
    override fun ccUserBlocked(user: User?) {
        super.ccUserBlocked(user)
    }

    override fun ccUserUnblocked(user: User?) {
        super.ccUserUnblocked(user)
    }
})
Remove Listener
CometChatUserEvents.removeListener("LISTENER_TAG")

SDK Events (Real-Time, Automatic)

The component listens to these SDK events internally. No manual attachment needed unless additional side effects are required.
SDK ListenerInternal behavior
onUserOnlineUpdates online status indicator for the user
onUserOfflineUpdates offline status indicator for the user
Automatic: user presence changes update the status indicator in real time.

Functionality

Small functional customizations such as toggling visibility of UI elements and configuring selection modes.
MethodsDescriptionCode
setBackIconVisibilityToggles visibility for the back button in the app bar.setBackIconVisibility(View.VISIBLE);
setToolbarVisibilityToggles visibility for the toolbar in the app bar.setToolbarVisibility(View.GONE);
setStickyHeaderVisibilityToggles visibility for the alphabetical sticky header.setStickyHeaderVisibility(View.GONE);
setLoadingStateVisibilityHides the loading state while fetching users.setLoadingStateVisibility(View.GONE);
setErrorStateVisibilityHides the error state on fetching users.setErrorStateVisibility(View.GONE);
setEmptyStateVisibilityHides the empty state on fetching users.setEmptyStateVisibility(View.GONE);
setSeparatorVisibilityControls visibility of separators in the list view.setSeparatorVisibility(View.GONE);
setUserStatusVisibilityControls visibility of the online status indicator.setUserStatusVisibility(View.GONE);
setSearchBoxVisibilityControls visibility of the search box in the toolbar.setSearchBoxVisibility(View.GONE);
setSelectionModeDetermines the selection mode (single or multiple).setSelectionMode(UIKitConstants.SelectionMode.MULTIPLE);
setSearchKeywordProgrammatically triggers a search with the given keyword.setSearchKeyword("john");
setTitleTextSets a custom title in the toolbar.setTitleText("Contacts");
setSearchPlaceholderTextSets the placeholder text for the search input.setSearchPlaceholderText("Find users...");
  • Verify: After calling a visibility method, confirm the corresponding UI element is shown or hidden.

Custom View Slots

Each slot replaces a section of the default UI. Slots that accept a User parameter receive the user object for that row via the UsersViewHolderListener pattern (createView + bindView).
SlotMethodReplaces
Leading viewsetLeadingView(UsersViewHolderListener)Avatar / left section
Title viewsetTitleView(UsersViewHolderListener)Name / title text
Subtitle viewsetSubtitleView(UsersViewHolderListener)Subtitle text below name
Trailing viewsetTrailingView(UsersViewHolderListener)Right section
Item viewseItemView(UsersViewHolderListener)Entire list item row (note: typo in SDK)
Loading viewsetLoadingView(@LayoutRes int)Loading spinner
Empty viewsetEmptyView(@LayoutRes int)Empty state
Error viewsetErrorView(@LayoutRes int)Error state
Overflow menusetOverflowMenu(View)Toolbar menu
Options (replace)setOptions(Function2)Long-press context menu (replaces defaults)
Options (append)addOptions(Function2)Long-press context menu (appends to defaults)

setLeadingView

Replace the avatar / left section.
cometchatUsers.setLeadingView(object : UsersViewHolderListener() {
    override fun createView(
        context: Context?,
        listItem: CometchatListBaseItemsBinding?
    ): View? {
        return null
    }

    override fun bindView(
        context: Context,
        createdView: View,
        user: User,
        holder: RecyclerView.ViewHolder,
        userList: List<User>,
        position: Int
    ) {
    }
})
What this does: Registers a UsersViewHolderListener that provides a custom view for the leading (left) area of each user item. createView inflates your layout, and bindView populates it with user data.

setTitleView

Replace the name / title text.
cometchatUsers.setTitleView(object : UsersViewHolderListener() {
    override fun createView(
        context: Context?,
        listItem: CometchatListBaseItemsBinding?
    ): View? {
        return null
    }

    override fun bindView(
        context: Context,
        createdView: View,
        user: User,
        holder: RecyclerView.ViewHolder,
        userList: List<User>,
        position: Int
    ) {
    }
})
Inline role badge example:
Create a custom_user_title_view.xml layout:
custom_user_title_view.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/user_layout"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:gravity="center_vertical"
    android:orientation="horizontal">

    <TextView
        android:id="@+id/title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:text="teacher"
        android:textAppearance="?attr/cometchatTextAppearanceHeading4Medium" />

    <View
        android:id="@+id/role"
        android:layout_width="50dp"
        android:layout_height="15dp"
        android:layout_marginStart="@dimen/cometchat_16dp"
        android:background="@drawable/teacher" />

</LinearLayout>
cometchatUsers.setTitleView(object : UsersViewHolderListener() {
    override fun createView(context: Context?, listItem: CometchatListBaseItemsBinding?): View {
        return LayoutInflater.from(context).inflate(R.layout.custom_user_title_view, null)
    }

    override fun bindView(
        context: Context,
        createdView: View,
        user: User,
        holder: RecyclerView.ViewHolder,
        userList: List<User>,
        position: Int
    ) {
        val layout = createdView.findViewById<LinearLayout>(R.id.user_layout)
        val layoutParams = LinearLayout.LayoutParams(
            ViewGroup.LayoutParams.WRAP_CONTENT,
            ViewGroup.LayoutParams.WRAP_CONTENT
        )
        layout.layoutParams = layoutParams
        val name = createdView.findViewById<TextView>(R.id.title)
        name.text = user.name
        val role = createdView.findViewById<View>(R.id.role)
        when (user.role) {
            "teacher" -> {
                role.visibility = View.VISIBLE
                role.background = ResourcesCompat.getDrawable(resources, R.drawable.teacher, null)
            }
            "student" -> {
                role.visibility = View.VISIBLE
                role.background = ResourcesCompat.getDrawable(resources, R.drawable.student, null)
            }
            "close_friend" -> {
                role.visibility = View.VISIBLE
                role.background = ResourcesCompat.getDrawable(resources, R.drawable.close_friend, null)
            }
            else -> role.visibility = View.GONE
        }
    }
})

setSubtitleView

Replace the subtitle text below the user’s name.
cometchatUsers.setSubtitleView(object : UsersViewHolderListener() {
    override fun createView(
        context: Context?,
        listItem: CometchatListBaseItemsBinding?
    ): View? {
        return null
    }

    override fun bindView(
        context: Context,
        createdView: View,
        user: User,
        holder: RecyclerView.ViewHolder,
        userList: List<User>,
        position: Int
    ) {
    }
})
Example with last-active timestamp:
cometchatUsers.setSubtitleView(object : UsersViewHolderListener() {
    override fun createView(
        context: Context?,
        listItem: 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 at: " + SimpleDateFormat("dd/MM/yyyy, HH:mm:ss").format(user.lastActiveAt * 1000)
        tvSubtitle.setTextColor(Color.BLACK)
    }
})

setTrailingView

Replace the right section of each user item.
cometchatUsers.setTrailingView(object : UsersViewHolderListener() {
    override fun createView(
        context: Context?,
        listItem: CometchatListBaseItemsBinding?
    ): View? {
        return null
    }

    override fun bindView(
        context: Context,
        createdView: View,
        user: User,
        holder: RecyclerView.ViewHolder,
        userList: List<User>,
        position: Int
    ) {
    }
})
Role tag badge example:
Create a custom_user_tail_view.xml layout:
custom_user_tail_view.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:gravity="center_vertical"
    android:orientation="horizontal">

    <View
        android:id="@+id/tag"
        android:layout_width="50dp"
        android:layout_height="15dp"
        android:layout_marginStart="@dimen/cometchat_16dp"
        android:background="@drawable/teacher" />

</LinearLayout>
cometchatUsers.setTrailingView(object : UsersViewHolderListener() {
    override fun createView(context: Context?, listItem: CometchatListBaseItemsBinding?): View {
        return LayoutInflater.from(context).inflate(R.layout.custom_user_tail_view, null)
    }

    override fun bindView(
        context: Context,
        createdView: View,
        user: User,
        holder: RecyclerView.ViewHolder,
        userList: List<User>,
        position: Int
    ) {
        val role = createdView.findViewById<View>(R.id.tag)
        if ("pro" == user.role) {
            role.visibility = View.VISIBLE
            role.background = ResourcesCompat.getDrawable(resources, R.drawable.teacher, null)
        } else {
            role.visibility = View.GONE
        }
    }
})

setItemView

Replace the entire list item row.
The Java method name is seItemView (note the missing ‘t’). This is a known typo in the SDK. In Kotlin, property access syntax normalizes this.
cometchatUsers.seItemView(object : UsersViewHolderListener() {
    override fun createView(
        context: Context?,
        listItem: CometchatListBaseItemsBinding?
    ): View? {
        return null
    }

    override fun bindView(
        context: Context,
        createdView: View,
        user: User,
        holder: RecyclerView.ViewHolder,
        userList: List<User>,
        position: Int
    ) {
    }
})
Example with online status background:
Create a custom_list_item_view.xml layout:
custom_list_item_view.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/parent_lay"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginStart="@dimen/cometchat_padding_4"
        android:layout_marginTop="@dimen/cometchat_padding_3"
        android:layout_marginEnd="@dimen/cometchat_padding_4"
        android:layout_marginBottom="@dimen/cometchat_padding_3"
        android:gravity="center_vertical"
        android:orientation="horizontal">

        <androidx.constraintlayout.widget.ConstraintLayout
            android:id="@+id/leading_view"
            android:layout_width="@dimen/cometchat_45dp"
            android:layout_height="@dimen/cometchat_45dp">

            <com.cometchat.chatuikit.shared.views.avatar.CometChatAvatar
                android:id="@+id/custom_avatar"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                app:cometchatAvatarPlaceHolderTextAppearance="@style/CometChatTextAppearanceHeading4.Bold"
                app:cometchatAvatarStrokeRadius="@dimen/cometchat_8dp" />

        </androidx.constraintlayout.widget.ConstraintLayout>

        <TextView
            android:id="@+id/tvName"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_marginStart="@dimen/cometchat_margin_3"
            android:layout_weight="1"
            android:textAppearance="@style/CometChatTextAppearanceHeading4.Medium" />

    </LinearLayout>

    <View
        android:layout_width="match_parent"
        android:layout_height="1dp"
        android:background="?attr/cometchatStrokeColorLight" />

</LinearLayout>
cometchatUsers.seItemView(object : UsersViewHolderListener() {
    override fun createView(
        context: Context?,
        listItem: CometchatListBaseItemsBinding?
    ): View {
        return LayoutInflater.from(context)
            .inflate(R.layout.custom_list_item_view, null, false)
    }

    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)
        val parentLayout = createdView.findViewById<LinearLayout>(R.id.parent_lay)
        val name = user.name
        title.text = name
        avatar.setStyle(com.cometchat.chatuikit.R.style.CometChatAvatarStyle)
        avatar.avatarPlaceHolderTextAppearance =
            com.cometchat.chatuikit.R.style.CometChatTextAppearanceHeading4_Bold
        avatar.setAvatar(name, user.avatar)
        if (user.status == UIKitConstants.UserStatus.ONLINE) {
            parentLayout.setBackgroundColor(Color.parseColor("#E6F4ED"))
        } else {
            parentLayout.setBackgroundColor(Color.parseColor("#00000000"))
        }
    }
})

setOptions

Replace the long-press context menu entirely.
cometchatUsers.setOptions { context, user -> emptyList<CometChatPopupMenu.MenuItem?>() }

addOptions

Append to the long-press context menu without removing defaults.
cometchatUsers.addOptions { context, user -> emptyList<CometChatPopupMenu.MenuItem?>() }

setLoadingView

Sets a custom loading view displayed when data is being fetched.
cometchatUsers.loadingView = R.layout.your_loading_view

setEmptyView

Configures a custom view displayed when there are no users in the list.
cometchatUsers.emptyView = R.layout.your_empty_view

setErrorView

Defines a custom error state view that appears when an issue occurs while loading users.
cometchatUsers.errorView = R.layout.your_error_view

setOverflowMenu

Replace the toolbar overflow menu.
val imageView = ImageView(requireContext())
imageView.setImageResource(R.drawable.ic_user_menu)
cometchatUsers.setOverflowMenu(imageView)
  • Verify: After setting any custom view slot, confirm the custom view renders in the correct position within the user list item, and the data binding populates correctly for each user.

Common Patterns

Hide all chrome — minimal list

cometChatUsers.setUserStatusVisibility(View.GONE)
cometChatUsers.setSeparatorVisibility(View.GONE)
cometChatUsers.setToolbarVisibility(View.GONE)
cometChatUsers.setStickyHeaderVisibility(View.GONE)

Friends-only list

val builder = UsersRequest.UsersRequestBuilder()
    .friendsOnly(true)
cometChatUsers.setUsersRequestBuilder(builder)

Online users only

val builder = UsersRequest.UsersRequestBuilder()
    .setUserStatus(CometChatConstants.USER_STATUS_ONLINE)
cometChatUsers.setUsersRequestBuilder(builder)

Advanced Methods

Programmatic Selection

selectUser

Programmatically selects or deselects a user. Works with both SINGLE and MULTIPLE selection modes.
// Select a user in single-select mode
cometChatUsers.selectUser(user, UIKitConstants.SelectionMode.SINGLE)

// Select a user in multi-select mode
cometChatUsers.selectUser(user, UIKitConstants.SelectionMode.MULTIPLE)
In SINGLE mode, selecting a new user replaces the previous selection. In MULTIPLE mode, calling this on an already-selected user deselects it (toggle behavior).

clearSelection

Clears all selected users and resets the selection UI.
cometChatUsers.clearSelection()

getSelectedUsers

Returns the list of currently selected User objects.
val selected = cometChatUsers.selectedUsers

Selected Users List

When using multi-select mode, a horizontal list of selected users can be shown above the main list.
MethodTypeDescription
setSelectedUsersListVisibilityint (View.VISIBLE / View.GONE)Show or hide the selected users strip
setSelectedUserAvatarStyle@StyleRes intAvatar style for selected user chips
setSelectedUserItemTextColor@ColorInt intText color for selected user names
setSelectedUserItemTextAppearance@StyleRes intText appearance for selected user names
setSelectedUserItemRemoveIconDrawableIcon for the remove button on each chip
setSelectedUserItemRemoveIconTint@ColorInt intTint color for the remove icon

Search Input Customization

The built-in search box can be customized programmatically:
MethodTypeDescription
setSearchPlaceholderTextStringSets the placeholder text for the search input
setSearchInputTextColor@ColorInt intText color of the search input
setSearchInputTextAppearance@StyleRes intText appearance of the search input
setSearchInputPlaceHolderTextColor@ColorInt intPlaceholder text color
setSearchInputPlaceHolderTextAppearance@StyleRes intPlaceholder text appearance
setSearchInputIconDrawableLeading icon in the search box
setSearchInputIconTint@ColorInt intTint for the leading icon
setSearchInputEndIconDrawableTrailing icon in the search box
setSearchInputEndIconTint@ColorInt intTint for the trailing icon
setSearchInputStrokeWidth@Dimension intStroke width of the search box border
setSearchInputStrokeColor@ColorInt intStroke color of the search box border
setSearchInputBackgroundColor@ColorInt intBackground color of the search box
setSearchInputCornerRadius@Dimension intCorner radius of the search box

Internal Access

These methods provide direct access to internal components for advanced use cases.
MethodReturnsDescription
getBinding()CometchatUserListBindingThe ViewBinding for the component’s root layout
getViewModel()UsersViewModelThe ViewModel managing user data and state
getUsersAdapter()UsersAdapterThe adapter powering the RecyclerView
setAdapter(UsersAdapter)voidReplaces the default adapter with a custom one
Use these only when the standard API is insufficient. Directly manipulating the adapter or ViewModel may conflict with the component’s internal state management.

Style

The component uses XML theme styles. Define a custom style with parent CometChatUsersStyle in themes.xml, then apply with setStyle().
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>
cometChatUsers.setStyle(R.style.CustomUsersStyle)
To know more such attributes, visit the attributes file.

Programmatic Style Properties

In addition to XML theme styles, the component exposes programmatic setters for fine-grained control:
MethodTypeDescription
setBackgroundColor@ColorInt intBackground color of the component
setBackIconTint@ColorInt intTint color for the back icon
setBackIconDrawableCustom back icon drawable
setTitleTextColor@ColorInt intTitle text color in the toolbar
setTitleTextAppearance@StyleRes intTitle text appearance in the toolbar
setItemTitleTextColor@ColorInt intText color for user item titles
setItemTitleTextAppearance@StyleRes intText appearance for user item titles
setItemBackgroundColor@ColorInt intBackground color for list items
setItemSelectedBackgroundColor@ColorInt intBackground color for selected list items
setSeparatorColor@ColorInt intColor of list item separators
setStrokeColor@ColorInt intStroke color of the component border
setStrokeWidth@Dimension intStroke width of the component border
setCornerRadius@Dimension intCorner radius of the component
setStickyTitleColor@ColorInt intText color for sticky alphabetical headers
setStickyTitleAppearance@StyleRes intText appearance for sticky headers
setStickyTitleBackgroundColor@ColorInt intBackground color for sticky headers
setEmptyStateTextColor@ColorInt intTitle text color for the empty state
setEmptyStateTextAppearance@StyleRes intTitle text appearance for the empty state
setEmptyStateSubtitleTextColor@ColorInt intSubtitle text color for the empty state
setEmptyStateSubTitleTextAppearance@StyleRes intSubtitle text appearance for the empty state
setErrorStateTextColor@ColorInt intTitle text color for the error state
setErrorStateTextAppearance@StyleRes intTitle text appearance for the error state
setErrorStateSubtitleColor@ColorInt intSubtitle text color for the error state
setErrorStateSubtitleTextAppearance@StyleRes intSubtitle text appearance for the error state
setRetryButtonTextColor@ColorInt intText color for the retry button
setRetryButtonTextAppearance@StyleRes intText appearance for the retry button
setRetryButtonBackgroundColor@ColorInt intBackground color for the retry button
setRetryButtonStrokeColor@ColorInt intStroke color for the retry button
setRetryButtonStrokeWidth@Dimension intStroke width for the retry button
setRetryButtonCornerRadius@Dimension intCorner radius for the retry button
setAvatarStyle@StyleRes intStyle for user avatars
setStatusIndicatorStyle@StyleRes intStyle for online/offline status indicators

Checkbox Style Properties (Selection Mode)

When using SINGLE or MULTIPLE selection mode, checkboxes appear on each item:
MethodTypeDescription
setCheckBoxStrokeWidth@Dimension intStroke width of the checkbox border
setCheckBoxCornerRadius@Dimension intCorner radius of the checkbox
setCheckBoxStrokeColor@ColorInt intStroke color of the checkbox border
setCheckBoxBackgroundColor@ColorInt intBackground color of unchecked checkbox
setCheckBoxCheckedBackgroundColor@ColorInt intBackground color of checked checkbox
setCheckBoxSelectIconDrawableIcon shown when checkbox is checked
setCheckBoxSelectIconTint@ColorInt intTint for the checkbox select icon
setDiscardSelectionIconDrawableIcon for the discard selection button
setDiscardSelectionIconTint@ColorInt intTint for the discard selection icon
setSubmitSelectionIconDrawableIcon for the submit selection button
setSubmitSelectionIconTint@ColorInt intTint for the submit selection icon

Customization Matrix

What to changeWhereProperty/APIExample
Override behavior on user interactionActivity/FragmentsetOn<Event> callbackssetOnItemClick((v, pos, u) -> { ... })
Filter which users appearActivity/FragmentsetUsersRequestBuildersetUsersRequestBuilder(builder)
Customize search resultsActivity/FragmentsetSearchRequestBuildersetSearchRequestBuilder(builder)
Toggle visibility of UI elementsActivity/Fragmentset<Feature>Visibility(int)setUserStatusVisibility(View.GONE)
Replace a section of the list itemActivity/Fragmentset<Slot>ViewsetLeadingView(listener)
Change colors, fonts, spacingthemes.xmlCometChatUsersStyle<item name="cometchatUsersSeparatorColor">#F76808</item>
Avatar style (corner radius, background)themes.xmlcometchatUsersAvatarStyle<item name="cometchatAvatarStrokeRadius">8dp</item>
Apply a custom styleActivity/FragmentsetStyle(int styleRes)cometChatUsers.setStyle(R.style.CustomUsersStyle);
Back button visibilityActivity/FragmentsetBackIconVisibility(int).setBackIconVisibility(View.VISIBLE);
Toolbar visibilityActivity/FragmentsetToolbarVisibility(int).setToolbarVisibility(View.GONE);
Sticky header visibilityActivity/FragmentsetStickyHeaderVisibility(int).setStickyHeaderVisibility(View.GONE);
Error state visibilityActivity/FragmentsetErrorStateVisibility(int).setErrorStateVisibility(View.GONE);
Empty state visibilityActivity/FragmentsetEmptyStateVisibility(int).setEmptyStateVisibility(View.GONE);
Loading state visibilityActivity/FragmentsetLoadingStateVisibility(int).setLoadingStateVisibility(View.GONE);
Separator visibilityActivity/FragmentsetSeparatorVisibility(int).setSeparatorVisibility(View.GONE);
User online status visibilityActivity/FragmentsetUserStatusVisibility(int).setUserStatusVisibility(View.GONE);
Selection mode (single/multiple)Activity/FragmentsetSelectionMode(SelectionMode).setSelectionMode(UIKitConstants.SelectionMode.MULTIPLE);
Search keywordActivity/FragmentsetSearchKeyword(String).setSearchKeyword("john");
Search box visibilityActivity/FragmentsetSearchBoxVisibility(int).setSearchBoxVisibility(View.GONE);
Custom toolbar titleActivity/FragmentsetTitleText(String).setTitleText("Contacts");
Search placeholderActivity/FragmentsetSearchPlaceholderText(String).setSearchPlaceholderText("Find users...");
Long-press options (replace)Activity/FragmentsetOptions(Function2)See setOptions code above
Long-press options (append)Activity/FragmentaddOptions(Function2)See addOptions code above
Loading viewActivity/FragmentsetLoadingView(int).setLoadingView(R.layout.your_loading_view);
Empty viewActivity/FragmentsetEmptyView(int).setEmptyView(R.layout.your_empty_view);
Error viewActivity/FragmentsetErrorView(int).setErrorView(R.layout.your_error_view);
Leading view (avatar area)Activity/FragmentsetLeadingView(UsersViewHolderListener)See setLeadingView code above
Title viewActivity/FragmentsetTitleView(UsersViewHolderListener)See setTitleView code above
Trailing viewActivity/FragmentsetTrailingView(UsersViewHolderListener)See setTrailingView code above
Entire list itemActivity/FragmentseItemView(UsersViewHolderListener)See setItemView code above
Subtitle viewActivity/FragmentsetSubtitleView(UsersViewHolderListener)See setSubtitleView code above
Overflow menuActivity/FragmentsetOverflowMenu(View)cometChatUsers.setOverflowMenu(view);
Programmatic selectionActivity/FragmentselectUser(User, SelectionMode).selectUser(user, SelectionMode.SINGLE);
Clear selectionActivity/FragmentclearSelection().clearSelection();
Selected users stripActivity/FragmentsetSelectedUsersListVisibility(int).setSelectedUsersListVisibility(View.VISIBLE);
Internal adapter accessActivity/FragmentgetUsersAdapter() / setAdapter()Advanced use only

Accessibility

The component renders a scrollable RecyclerView of interactive user items. Each user row responds to tap and long-press gestures. Avatar images include the user name as content description. The alphabetical sticky headers provide section navigation for screen readers. For custom views provided via setLeadingView, setTitleView, setTrailingView, or seItemView, ensure you set android:contentDescription on visual-only elements so TalkBack can announce them. The default views handle this automatically. Online/offline status dots are visual-only by default. If screen reader descriptions are needed, provide them via a custom view with appropriate contentDescription attributes.

Next Steps