Skip to main content
CometChatGroups renders a scrollable list of all available groups with real-time updates for membership changes, search, avatars, and group type indicators (public, private, password-protected).

Where It Fits

CometChatGroups is a list component. It renders all available groups and emits the selected Group via onItemClick. Wire it to CometChatMessageHeader, CometChatMessageList, and CometChatMessageComposer to build a group messaging layout.
activity_chat.xml
<com.cometchat.uikit.kotlin.presentation.groups.ui.CometChatGroups
    android:id="@+id/groups"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />
val groups = findViewById<CometChatGroups>(R.id.groups)

groups.setOnItemClick { group ->
    messageHeader.setGroup(group)
    messageList.setGroup(group)
    messageComposer.setGroup(group)
}

Quick Start

Add to your layout XML:
<com.cometchat.uikit.kotlin.presentation.groups.ui.CometChatGroups
    android:id="@+id/groups"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />
Or programmatically:
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(CometChatGroups(this))
}
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 {
    return CometChatGroups(requireContext())
}

Filtering Groups

Pass a GroupsRequest.GroupsRequestBuilder to control what loads:
groups.setGroupsRequestBuilder(
    GroupsRequest.GroupsRequestBuilder()
        .joinedOnly(true)
        .setLimit(20)
)

Filter Recipes

RecipeBuilder method
Joined only.joinedOnly(true)
Limit per page.setLimit(10)
Search by keyword.setSearchKeyWord("design")
Filter by tags.setTags(listOf("vip"))
With tags.withTags(true)
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 group row is tapped. Primary navigation hook.
groups.setOnItemClick { group ->
    // Navigate to group chat screen
}
Replaces the default item-click behavior. Your custom lambda executes instead of the built-in navigation.

onItemLongClick

Fires when a group row is long-pressed. Use for additional actions like delete or leave.
groups.setOnItemLongClick { group ->
    // Show context menu
}

onBackPress

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

onSearchClick

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

onSelection

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

onError

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

onLoad

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

onEmpty

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

SDK Events (Real-Time, Automatic)

The component listens to these SDK events internally. No manual setup needed.
SDK ListenerInternal behavior
onGroupMemberJoinedUpdates the group list when a member joins
onGroupMemberLeftUpdates the group list when a member leaves
onGroupMemberKickedUpdates the group list when a member is kicked
onGroupMemberBannedUpdates the group list when a member is banned
onGroupMemberUnbannedUpdates the group list when a member is unbanned
onGroupMemberScopeChangedUpdates the group list when a member’s scope changes
onMemberAddedToGroupUpdates the group list when members are added

Functionality

Method (Kotlin XML)Compose ParameterDescription
setBackIconVisibility(View.VISIBLE)hideBackIcon = falseToggle back button
setToolbarVisibility(View.GONE)hideToolbar = trueToggle toolbar
setSearchBoxVisibility(View.GONE)hideSearchBox = trueToggle search box
setGroupTypeVisibility(View.GONE)hideGroupType = trueToggle group type indicator
setSeparatorVisibility(View.GONE)hideSeparator = trueToggle list separators
setSelectionMode(MULTIPLE)selectionMode = MULTIPLEEnable selection mode
setTitle("My Groups")title = "My Groups"Custom toolbar title
setSearchPlaceholderText("Find...")searchPlaceholderText = "Find..."Search placeholder

Custom View Slots

Leading View

Replace the avatar / left section.
groups.setLeadingView(object : GroupsViewHolderListener() {
    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, group: Group,
        holder: RecyclerView.ViewHolder, groupList: List<Group>, position: Int
    ) {
        val imageView = createdView as ImageView
        // Load group avatar
    }
})

Title View

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

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

Subtitle View

Replace the subtitle text below the group name.
groups.setSubtitleView(object : GroupsViewHolderListener() {
    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, group: Group,
        holder: RecyclerView.ViewHolder, groupList: List<Group>, position: Int
    ) {
        (createdView as TextView).text = "${group.membersCount} members"
    }
})

Trailing View

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

    override fun bindView(
        context: Context, createdView: View, group: Group,
        holder: RecyclerView.ViewHolder, groupList: List<Group>, position: Int
    ) {
        (createdView as TextView).text = if (group.isJoined) "Joined" else "Join"
    }
})

Item View

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

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

State Views

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

Overflow Menu

groups.setOverflowMenu(ImageButton(context).apply {
    setImageResource(R.drawable.ic_create_group)
    setOnClickListener { /* create group */ }
})

// Replace all options
groups.setOptions { context, group ->
    listOf(
        CometChatPopupMenu.MenuItem(id = "leave", name = "Leave", onClick = { /* ... */ }),
        CometChatPopupMenu.MenuItem(id = "delete", name = "Delete", onClick = { /* ... */ })
    )
}

// Append to defaults
groups.setAddOptions { context, group ->
    listOf(
        CometChatPopupMenu.MenuItem(id = "pin", name = "Pin", onClick = { /* ... */ })
    )
}

Common Patterns

Minimal list — hide all chrome

groups.setToolbarVisibility(View.GONE)
groups.setSearchBoxVisibility(View.GONE)
groups.setGroupTypeVisibility(View.GONE)

Joined groups only

groups.setGroupsRequestBuilder(
    GroupsRequest.GroupsRequestBuilder()
        .joinedOnly(true)
)

Tagged groups

groups.setGroupsRequestBuilder(
    GroupsRequest.GroupsRequestBuilder()
        .setTags(listOf("support"))
        .withTags(true)
)

Advanced Methods

Programmatic Selection

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

// Select a group
groups.selectGroup(group, UIKitConstants.SelectionMode.MULTIPLE)

// Get selected
val selected = groups.getSelectedGroups()

// Clear
groups.clearSelection()

ViewModel Access

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

Style

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

<style name="CustomGroupsStyle" parent="CometChatGroupsStyle">
    <item name="cometchatGroupsAvatarStyle">@style/CustomGroupsAvatarStyle</item>
    <item name="cometchatGroupsSeparatorColor">#F76808</item>
    <item name="cometchatGroupsTitleTextColor">#F76808</item>
</style>

<style name="AppTheme" parent="CometChatTheme.DayNight">
    <item name="cometchatGroupsStyle">@style/CustomGroupsStyle</item>
</style>

Style Properties

PropertyDescription
backgroundColorList background color
titleTextColorToolbar title color
searchBoxStyleSearch box appearance
itemStyle.backgroundColorRow background
itemStyle.selectedBackgroundColorSelected row background
itemStyle.titleTextColorGroup name color
itemStyle.subtitleTextColorSubtitle text color
itemStyle.separatorColorRow separator color
itemStyle.avatarStyleAvatar appearance
itemStyle.statusIndicatorStyleGroup type indicator
See Component Styling for the full reference.

Next Steps

Group Members

View and manage group members

Conversations

Browse recent conversations

Component Styling

Detailed styling reference with screenshots

ViewModel & Data

Custom ViewModels, repositories, and ListOperations