Skip to main content
CometChatGroupMembers renders a scrollable list of all members in a specific group with real-time updates for membership changes, search, avatars, scope badges, and online/offline status indicators. Requires a Group object to load data.

Where It Fits

CometChatGroupMembers is a list component. It renders all members of a given group and emits the selected GroupMember via onItemClick. Use it inside a group detail screen or as a standalone member browser.
activity_group_members.xml
<com.cometchat.uikit.kotlin.presentation.groupmembers.ui.CometChatGroupMembers
    android:id="@+id/group_members"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />
val groupMembers = findViewById<CometChatGroupMembers>(R.id.group_members)
groupMembers.setGroup(group)

groupMembers.setOnItemClick { groupMember ->
    // Navigate to member profile or start DM
}

Quick Start

Add to your layout XML:
<com.cometchat.uikit.kotlin.presentation.groupmembers.ui.CometChatGroupMembers
    android:id="@+id/group_members"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />
Then set the group in your Activity:
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_group_members)

    val groupMembers = findViewById<CometChatGroupMembers>(R.id.group_members)
    groupMembers.setGroup(group) // Required — must be called before data loads
}
Prerequisites: CometChat SDK initialized with CometChatUIKit.init(), a user logged in, and the UI Kit dependency added. Or in a Fragment:
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
    val view = CometChatGroupMembers(requireContext())
    view.setGroup(group)
    return view
}

Filtering Group Members

Pass a GroupMembersRequest.GroupMembersRequestBuilder to control what loads:
groupMembers.setGroupMembersRequestBuilder(
    GroupMembersRequest.GroupMembersRequestBuilder(group.guid)
        .setLimit(20)
        .setScopes(listOf("admin", "moderator"))
)

Filter Recipes

RecipeBuilder method
Limit per page.setLimit(10)
Search by keyword.setSearchKeyword("john")
Filter by scopes.setScopes(listOf("admin", "moderator"))
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 member row is tapped. Primary navigation hook.
groupMembers.setOnItemClick { groupMember ->
    // Navigate to member profile
}
Replaces the default item-click behavior. Your custom lambda executes instead of the built-in navigation.

onItemLongClick

Fires when a member row is long-pressed. Use for additional actions like kick or ban.
groupMembers.setOnItemLongClick { groupMember ->
    // Show context menu
}

onBackPress

Fires when the user presses the back button in the toolbar.
groupMembers.setOnBackPress {
    finish()
}

onSearchClick

Fires when the user taps the search icon in the toolbar.
groupMembers.setOnSearchClick {
    // Open search screen
}

onSelection

Fires when members are selected/deselected in multi-select mode.
groupMembers.setSelectionMode(UIKitConstants.SelectionMode.MULTIPLE)
groupMembers.setOnSelection { selectedMembers ->
    updateToolbar(selectedMembers.size)
}

onError

Fires on internal errors (network failure, auth issue, SDK exception).
groupMembers.setOnError { exception ->
    Log.e("GroupMembers", "Error: ${exception.message}")
}

onLoad

Fires when the list is successfully fetched and loaded.
groupMembers.setOnLoad { memberList ->
    Log.d("GroupMembers", "Loaded ${memberList.size}")
}

onEmpty

Fires when the list is empty after loading.
groupMembers.setOnEmpty {
    Log.d("GroupMembers", "No members found")
}

SDK Events (Real-Time, Automatic)

The component listens to these SDK events internally. No manual setup needed.
SDK ListenerInternal behavior
onGroupMemberJoinedAdds the new member to the list
onGroupMemberLeftRemoves the member from the list
onGroupMemberKickedRemoves the kicked member
onGroupMemberBannedRemoves the banned member
onGroupMemberUnbannedUpdates the member list
onGroupMemberScopeChangedUpdates the member’s scope badge
onMemberAddedToGroupAdds new members to the list

Functionality

Method (Kotlin XML)Compose ParameterDescription
setGroup(group)group = groupSet the group to load members for (required)
setBackIconVisibility(View.VISIBLE)hideBackIcon = falseToggle back button
setToolbarVisibility(View.GONE)hideToolbar = trueToggle toolbar
setSearchBoxVisibility(View.GONE)hideSearchBox = trueToggle search box
setSeparatorVisibility(View.GONE)hideSeparator = trueToggle list separators
setSelectionMode(MULTIPLE)selectionMode = MULTIPLEEnable selection mode
setTitle("Members")title = "Members"Custom toolbar title
setSearchPlaceholderText("Find...")searchPlaceholderText = "Find..."Search placeholder

Custom View Slots

Leading View

Replace the avatar / left section.
groupMembers.setLeadingView(object : GroupMembersViewHolderListener() {
    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, groupMember: GroupMember,
        holder: RecyclerView.ViewHolder, memberList: List<GroupMember>, position: Int
    ) {
        val imageView = createdView as ImageView
        // Load member avatar
    }
})

Title View

Replace the name / title text.
groupMembers.setTitleView(object : GroupMembersViewHolderListener() {
    override fun createView(context: Context, binding: CometchatListBaseItemsBinding): View {
        return TextView(context)
    }

    override fun bindView(
        context: Context, createdView: View, groupMember: GroupMember,
        holder: RecyclerView.ViewHolder, memberList: List<GroupMember>, position: Int
    ) {
        (createdView as TextView).text = groupMember.name ?: ""
    }
})

Subtitle View

Replace the subtitle text below the member’s name.
groupMembers.setSubtitleView(object : GroupMembersViewHolderListener() {
    override fun createView(context: Context, binding: CometchatListBaseItemsBinding): View {
        return TextView(context).apply { maxLines = 1; ellipsize = TextUtils.TruncateAt.END }
    }

    override fun bindView(
        context: Context, createdView: View, groupMember: GroupMember,
        holder: RecyclerView.ViewHolder, memberList: List<GroupMember>, position: Int
    ) {
        (createdView as TextView).text = "Scope: ${groupMember.scope}"
    }
})

Trailing View

Replace the right section of each member item.
groupMembers.setTrailingView(object : GroupMembersViewHolderListener() {
    override fun createView(context: Context, binding: CometchatListBaseItemsBinding): View {
        return TextView(context)
    }

    override fun bindView(
        context: Context, createdView: View, groupMember: GroupMember,
        holder: RecyclerView.ViewHolder, memberList: List<GroupMember>, position: Int
    ) {
        (createdView as TextView).text = groupMember.scope ?: ""
    }
})

Item View

Replace the entire list item row.
groupMembers.setItemView(object : GroupMembersViewHolderListener() {
    override fun createView(context: Context, binding: CometchatListBaseItemsBinding): View {
        return LayoutInflater.from(context).inflate(R.layout.custom_member_item, null)
    }

    override fun bindView(
        context: Context, createdView: View, groupMember: GroupMember,
        holder: RecyclerView.ViewHolder, memberList: List<GroupMember>, position: Int
    ) {
        val avatar = createdView.findViewById<CometChatAvatar>(R.id.custom_avatar)
        val title = createdView.findViewById<TextView>(R.id.tvName)
        title.text = groupMember.name
        avatar.setAvatar(groupMember.name, groupMember.avatar)
    }
})

State Views

groupMembers.setEmptyView(R.layout.custom_empty_view)
groupMembers.setErrorView(R.layout.custom_error_view)
groupMembers.setLoadingView(R.layout.custom_loading_view)

Overflow Menu

groupMembers.setOverflowMenu(ImageButton(context).apply {
    setImageResource(R.drawable.ic_add_member)
    setOnClickListener { /* add member */ }
})

// Replace all options
groupMembers.setOptions { context, groupMember ->
    listOf(
        CometChatPopupMenu.MenuItem(id = "kick", name = "Kick", onClick = { /* ... */ }),
        CometChatPopupMenu.MenuItem(id = "ban", name = "Ban", onClick = { /* ... */ })
    )
}

// Append to defaults
groupMembers.setAddOptions { context, groupMember ->
    listOf(
        CometChatPopupMenu.MenuItem(id = "promote", name = "Promote", onClick = { /* ... */ })
    )
}

Common Patterns

Minimal list — hide all chrome

groupMembers.setToolbarVisibility(View.GONE)
groupMembers.setSearchBoxVisibility(View.GONE)
groupMembers.setSeparatorVisibility(View.GONE)

Admins and moderators only

groupMembers.setGroupMembersRequestBuilder(
    GroupMembersRequest.GroupMembersRequestBuilder(group.guid)
        .setScopes(listOf("admin", "moderator"))
)

Advanced Methods

Programmatic Selection

// Enable selection
groupMembers.setSelectionMode(UIKitConstants.SelectionMode.MULTIPLE)

// Select a member
groupMembers.selectGroupMember(member, UIKitConstants.SelectionMode.MULTIPLE)

// Get selected
val selected = groupMembers.getSelectedGroupMembers()

// Clear
groupMembers.clearSelection()

ViewModel Access

val factory = CometChatGroupMembersViewModelFactory()
val viewModel = ViewModelProvider(this, factory)
    .get(CometChatGroupMembersViewModel::class.java)
groupMembers.setViewModel(viewModel)
See ViewModel & Data for ListOperations, state observation, and custom repositories.

Style

Define a custom style in themes.xml:
themes.xml
<style name="CustomGroupMembersAvatarStyle" parent="CometChatAvatarStyle">
    <item name="cometchatAvatarStrokeRadius">8dp</item>
    <item name="cometchatAvatarBackgroundColor">#FBAA75</item>
</style>

<style name="CustomGroupMembersStyle" parent="CometChatGroupMembersStyle">
    <item name="cometchatGroupMembersAvatarStyle">@style/CustomGroupMembersAvatarStyle</item>
    <item name="cometchatGroupMembersSeparatorColor">#F76808</item>
    <item name="cometchatGroupMembersTitleTextColor">#F76808</item>
</style>

<style name="AppTheme" parent="CometChatTheme.DayNight">
    <item name="cometchatGroupMembersStyle">@style/CustomGroupMembersStyle</item>
</style>

Style Properties

PropertyDescription
backgroundColorList background color
titleTextColorToolbar title color
searchBoxStyleSearch box appearance
itemStyle.backgroundColorRow background
itemStyle.selectedBackgroundColorSelected row background
itemStyle.titleTextColorMember 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

Groups

Browse and search available groups

Conversations

Browse recent conversations

Component Styling

Detailed styling reference with screenshots

ViewModel & Data

Custom ViewModels, repositories, and ListOperations