Skip to main content
CometChatMessageList displays a list of messages for a conversation and manages real-time message operations. It renders various message types including text, media, stickers, and more using MessageBubble components.

When to use this

  • You need a scrollable list of messages for a one-on-one or group conversation.
  • You want real-time updates when new messages arrive, are edited, or deleted.
  • You need support for threaded replies, reactions, and message actions (copy, edit, delete, translate, report).
  • You want to customize message bubble appearance, date/time formatting, and message filtering.
  • You need AI-powered features such as smart replies, conversation starters, conversation summaries, or AI assistant integration.
  • You want to add custom header or footer views above or below the message list.

Prerequisites

  • CometChat SDK initialized with CometChatUIKit.init() and a user logged in.
  • The cometchat-chat-uikit-android dependency added to your project.
  • A valid User or Group object to pass to the component (the component does not load messages without one).

Quick start

  1. Open your layout XML file (e.g., layout_activity.xml).
  2. Add the CometChatMessageList XML element:
layout_activity.xml
<com.cometchat.chatuikit.messagelist.CometChatMessageList
                android:id="@+id/message_list"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_marginStart="16dp"
                android:layout_marginEnd="16dp"
                android:background="@android:color/transparent" />
What this does: Adds the CometChatMessageList component to your layout. It fills the available width and height with transparent background and 16dp horizontal margins.
  1. In your Activity or Fragment, get a reference to the component and set a User or Group object:
YourActivity.java
CometChatMessageList cometChatMessageList = findViewById(R.id.message_list);
cometChatMessageList.setUser(user);
What this does: Gets a reference to the CometChatMessageList from the layout and sets the User object. The component fetches and displays messages for that user’s conversation.
  1. Build and run your app.
  2. Verify that the message list appears with message bubbles, timestamps, and read receipts.
  1. If you need to display messages for a group conversation instead, call .setGroup(group) with a Group object instead of .setUser(user).
Simply adding the MessageList component to the layout will only display the loading indicator. To fetch messages for a specific entity, you need to supplement it with User or Group Object.

Core concepts

  • CometChatMessageList: The main component class that renders a scrollable list of messages. It must be supplied with a User or Group object to fetch messages.
  • Message bubbles: Each message is rendered as a MessageBubble component. The bubble type depends on the message type (text, media, sticker, etc.). See MessageBubble styling for details.
  • Actions: Callbacks such as setOnThreadRepliesClick, setOnError, setOnReactionClick, and setOnReactionLongClick that let you respond to user interactions.
  • Filters: Use MessagesRequest.MessagesRequestBuilder to filter messages by search keyword, UID, or other criteria.
  • Events: The MessageList component does not emit any events of its own.
  • Style: XML theme styles (parent CometChatMessageListStyle) applied via setStyle() to customize colors, fonts, and sub-component styles.
  • Advanced views: Methods like setHeaderView, setFooterView, setLoadingView, setEmptyView, setErrorView, setDateTimeFormatter, and setTextFormatters that let you replace default UI elements with custom layouts.

Implementation

Actions

What you’re changing: How the component responds to user interactions such as thread reply taps, errors, load completion, empty states, and reaction interactions.
  • Where: Activity or Fragment where you hold a reference to CometChatMessageList (e.g., cometchatMessageList).
  • Applies to: CometChatMessageList.
  • Default behavior: Predefined actions execute automatically (e.g., tapping a threaded message bubble has no predefined behavior for onThreadRepliesClick).
  • Override: Call the corresponding setter method to replace the default behavior with your own logic.

setOnThreadRepliesClick

Triggered when you click on the threaded message bubble. The onThreadRepliesClick action does not have a predefined behavior.
cometchatMessageList.setOnThreadRepliesClick((context, baseMessage, cometchatMessageTemplate) -> {

        });
What this does: Registers a callback that fires when a user taps a threaded message bubble. The callback receives the context, the baseMessage, and the cometchatMessageTemplate.

setOnError

Listens for any errors that occur in the MessageList component. This does not change the component’s behavior.
YourActivity.java
cometchatMessageList.setOnError(new OnError() {
    @Override
    public void onError(CometChatException e) {
        //Your Exception Handling code.
    }
});
What this does: Registers an error listener. If the component encounters an error (e.g., network failure), your callback receives the CometChatException.

setOnLoad

Invoked when the list is successfully fetched and loaded, helping track component readiness.
YourActivity.java
cometchatMessageList.setOnLoad(list -> {

});
What this does: Registers a callback that fires after the message list is fetched and rendered. The callback receives the list of loaded BaseMessage objects.

setOnEmpty

Called when the list is empty, enabling custom handling such as showing a placeholder message.
YourActivity.java
cometchatMessageList.setOnEmpty(() -> {
            
    });
What this does: Registers a callback that fires when the message list has no items. Use this to show a custom empty-state message or trigger other logic.

setOnReactionLongClick

Triggered when a user long presses on a reaction pill.
YourActivity.java
cometchatMessageList.setOnReactionLongClick((emoji, baseMessage) -> {

    });
What this does: Replaces the default reaction long-press behavior. When a user long-presses a reaction pill, your custom lambda executes with the emoji and baseMessage.

setOnAddMoreReactionsClick

Triggered when a user clicks on the “Add More Reactions” button.
YourActivity.java
cometchatMessageList.setOnAddMoreReactionsClick(baseMessage -> {
            
    });
What this does: Replaces the default “Add More Reactions” button behavior. Your callback receives the baseMessage that the user wants to react to.

setOnReactionClick

Triggered when a reaction is clicked, enabling custom reaction interactions.
YourActivity.java
cometchatMessageList.setOnReactionClick((emoji, baseMessage) -> {

    });
What this does: Replaces the default reaction-click behavior. When a user taps a reaction, your custom lambda executes with the emoji and baseMessage.

setOnReactionListItemClick

Triggered when a reaction list item is clicked in CometChatReactionsList.
YourActivity.java
cometchatMessageList.setOnReactionListItemClick((reaction, message) -> {

    });
What this does: Replaces the default reaction list item click behavior. Your callback receives the reaction and message objects.
  • Verify: After setting an action callback, trigger the corresponding user interaction (thread reply tap, reaction click, reaction long-press) and confirm your custom logic executes instead of the default behavior.

Filters

What you’re changing: Which messages appear in the list.
  • Where: Activity or Fragment where you hold a reference to CometChatMessageList.
  • Applies to: CometChatMessageList.
  • Default behavior: All messages for the specified User or Group are fetched and displayed.
  • Override: Create a MessagesRequest.MessagesRequestBuilder, configure it, and pass it to setMessagesRequestBuilder.
  • Code:
MessagesRequest.MessagesRequestBuilder messagesRequest = new MessagesRequest.MessagesRequestBuilder()
    .setSearchKeyword("your search keyword")
    .setUID("user uid");

messageList.setMessagesRequestBuilder(messagesRequest);
What this does: Creates a MessagesRequestBuilder that filters messages by a search keyword and a specific user UID. The builder is then applied to the CometChatMessageList component.
The following parameters in messageRequestBuilder will always be altered inside the message list
  1. UID
  2. GUID
  3. types
  4. categories
For additional details on MessagesRequestBuilder, visit MessagesRequestBuilder.
  • Verify: The message list shows only messages matching the search keyword for the specified user.

Events

What you’re changing: How your app reacts to global events emitted by the MessageList component.
  • Where: Any Activity, Fragment, or class.
  • Applies to: CometChatMessageList.
  • Default behavior: The MessageList component does not emit any events of its own.
  • Override: Not applicable. If you need to listen for message-level events, use the CometChat SDK’s message listeners directly.
  • Verify: Not applicable — the MessageList component does not emit events.

Style

What you’re changing: The visual appearance of the MessageList component using XML theme styles.
  • Where: themes.xml for style definitions, and your Activity/Fragment for applying the style.
  • Applies to: CometChatMessageList.
  • Default behavior: The component uses the default CometChatMessageListStyle.
  • Override: Define a custom style with parent CometChatMessageListStyle in themes.xml, then call setStyle() on the component.
  • Code:
themes.xml
    <style name="CustomOutgoingMessageBubbleStyle" parent="CometChatOutgoingMessageBubbleStyle">
        <item name="cometchatMessageBubbleBackgroundColor">#F76808</item>
    </style>

    <style name="CustomCometChatMessageListStyle" parent="CometChatMessageListStyle">
        <item name="cometchatMessageListBackgroundColor">#FEEDE1</item>
        <item name="cometchatMessageListOutgoingMessageBubbleStyle">@style/CustomOutgoingMessageBubbleStyle</item>
    </style>
What this does: Defines two custom styles: CustomOutgoingMessageBubbleStyle sets the outgoing message bubble background to orange (#F76808); CustomCometChatMessageListStyle sets the message list background to light peach (#FEEDE1) and applies the custom outgoing bubble style.
cometChatMessageList.setStyle(R.style.CustomCometChatMessageListStyle);
What this does: Applies the CustomCometChatMessageListStyle theme to the CometChatMessageList component, changing the background color and outgoing message bubble appearance.
To know more such attributes, visit the attributes file.
  • Verify: The message list background displays as light peach (#FEEDE1) and outgoing message bubbles display with an orange background (#F76808).

Functionality

What you’re changing: Small functional customizations such as toggling visibility of UI elements, setting custom sounds, configuring alignment, and enabling AI features.
  • Where: Activity or Fragment where you hold a reference to CometChatMessageList.
  • Applies to: CometChatMessageList.
  • Default behavior: All UI elements are visible with default settings.
  • Override: Call the corresponding method on the component instance.
CometChatMessageList cometChatMessageList = findViewById(R.id.message_list);
cometChatMessageList.setUser(user);
cometChatMessageList.hideError(true);
cometChatMessageList.hideReceipt(true);
What this does: Gets a reference to the CometChatMessageList, sets the user, hides the error state, and hides read receipts.
PropertyDescriptionCode
setUserUsed to pass user object of which header specific details will be shown.setUser(user);
setGroupUsed to pass group object of which header specific details will be shown.setGroup(Group);
setAlignmentUsed to set the alignment of messages in CometChatMessageList. It can be either leftAligned or standard.setAlignment(UIKitConstants.MessageListAlignment);
setErrorStateVisibilityUsed to toggle visibility of error state in MessageList.setErrorStateVisibility(View.GONE);
disableSoundForMessagesUsed to enable/disable sound for incoming/outgoing messages, default false.disableSoundForMessages(false);
setCustomSoundForMessagesUsed to set custom sound for outgoing message.setCustomSoundForMessages(@RawRes resource);
setAvatarVisibilityUsed to toggle visibility for avatar.setAvatarVisibility(View.GONE);
scrollToBottomOnNewMessageIf true, scrolls to bottom on new message. Default is false.scrollToBottomOnNewMessage(true);
setReceiptsVisibilityUsed to control visibility of read receipts without disabling the functionality of marking messages as read and delivered.setReceiptsVisibility(View.GONE);
setQuickReactionsThe list of quick reactions to be set. This list replaces the predefined set of reactions.setQuickReactions(Arrays.asList("👻","😈","🙀","🤡","❤️");
setStickyDateVisibilityUsed to toggle visibility for sticky header.setStickyDateVisibility(View.GONE);
replyInThreadOptionVisibilityUsed to toggle visibility for thread option.replyInThreadOptionVisibility(View.GONE);
translateMessageOptionVisibilityUsed to toggle visibility for translate option.translateMessageOptionVisibility(View.GONE);
editMessageOptionVisibilityUsed to toggle visibility for edit option.editMessageOptionVisibility(View.GONE);
deleteMessageOptionVisibilityUsed to toggle visibility for delete option.deleteMessageOptionVisibility(View.GONE);
setMessageReactionOptionVisibilityUsed to toggle visibility for reaction option.setMessageReactionOptionVisibility(View.GONE);
messagePrivatelyOptionVisibilityUsed to toggle visibility for private option.messagePrivatelyOptionVisibility(View.GONE);
copyMessageOptionVisibilityUsed to toggle visibility for copy option.copyMessageOptionVisibility(View.GONE);
messageInfoOptionVisibilityUsed to toggle visibility for info option.messageInfoOptionVisibility(View.GONE);
groupActionMessageVisibilityUsed to toggle visibility for action message option.groupActionMessageVisibility(View.GONE);
enableConversationStartersControls whether conversation starters are generated in new conversations.enableConversationStarters(true);
| enableSmartReplies | Enables smart replies for quick responses | .enableSmartReplies(true); | | smartRepliesKeywords | Defines specific keywords in an incoming message that trigger Smart Replies | .setAISmartRepliesKeywords(Arrays.asList("hello", "hi", "how are you", "good morning", "good evening", "good night")); | | smartRepliesDelayDuration | Sets the delay time before Smart Replies are fetched and displayed after a message is received | .smartRepliesDelayDuration(5000); | | refreshStyle | Used to refresh the style of message list | .refreshStyle(); | | generateConversationSummary | Triggers the generation of a conversation summary by fetching it from the ViewModel | .generateConversationSummary(); |
  • Verify: After calling a visibility method, confirm the corresponding UI element is shown or hidden. After calling disableSoundForMessages(true), confirm no sound plays on incoming messages.

Advanced views

What you’re changing: The default UI elements of the message list including loading, empty, error states, date/time formatting, text formatting, header/footer views, AI assistant views, and message templates.
  • Where: Activity or Fragment where you hold a reference to CometChatMessageList.
  • Applies to: CometChatMessageList.
  • Default behavior: The component renders its built-in views for loading, empty, error states, date separators, message timestamps, and message content.
  • Override: Call the corresponding setter method and provide a custom view, layout resource, or callback.

SetTemplate

CometChatMessageTemplate is a pre-defined structure for creating message views that can be used as a starting point or blueprint for creating message views often known as message bubbles. For more information, refer to CometChatMessageTemplate.

setDateFormat

Specifies a custom format for displaying sticky date separators in the chat.
messageList.setDateFormat(new SimpleDateFormat("MMM dd, yyyy",Locale.getDefault()));
What this does: Sets the sticky date separator format to “MMM dd, yyyy” (e.g., “Jul 10, 2024”) using the device’s default locale.

setDateTimeFormatter

Provides a custom implementation of DateTimeFormatterCallback to configure how time and date values are displayed. Each method corresponds to a specific case:
  • time(long timestamp) — Custom full timestamp format
  • today(long timestamp) — Called when a message is from today
  • yesterday(long timestamp) — Called for yesterday’s messages
  • lastWeek(long timestamp) — Messages from the past week
  • otherDays(long timestamp) — Older messages
  • minute(long timestamp) / hour(long timestamp) — Exact time unit
  • minutes(long diffInMinutesFromNow, long timestamp) — e.g., “5 minutes ago”
  • hours(long diffInHourFromNow, long timestamp) — e.g., “2 hours ago”
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;


cometchatMessageList.setDateTimeFormatter(new DateTimeFormatterCallback() {

        private final SimpleDateFormat fullTimeFormatter = new SimpleDateFormat("hh:mm a", Locale.getDefault());
        private final SimpleDateFormat dateFormatter = new SimpleDateFormat("dd MMM yyyy", Locale.getDefault());

        @Override
        public String time(long timestamp) {
            return fullTimeFormatter.format(new Date(timestamp));
        }

        @Override
        public String today(long timestamp) {
            return "Today";
        }

        @Override
        public String yesterday(long timestamp) {
            return "Yesterday";
        }

        @Override
        public String lastWeek(long timestamp) {
            return "Last Week";
        }

        @Override
        public String otherDays(long timestamp) {
            return dateFormatter.format(new Date(timestamp));
        }

        @Override
        public String minutes(long diffInMinutesFromNow, long timestamp) {
            return diffInMinutesFromNow + " mins ago";
        }

        @Override
        public String hours(long diffInHourFromNow, long timestamp) {
            return diffInHourFromNow + " hrs ago";
        }
    });
What this does: Overrides the default date/time formatting for message timestamps. Today’s messages show “Today”, yesterday’s show “Yesterday”, recent messages show “X mins ago” or “X hrs ago”, last week’s show “Last Week”, and older messages show the full date in “dd MMM yyyy” format.

setTimeFormat

Defines the format in which time appears for each message bubble.
messageList.setTimeFormat(new SimpleDateFormat("hh:mm a",Locale.getDefault()));
What this does: Sets the message bubble time format to “hh:mm a” (e.g., “02:30 PM”) using the device’s default locale.

setLoadingView

Customizes the loading indicator when messages are being fetched.
cometchatMessageList.setLoadingView(R.layout.your_loading_view);
What this does: Replaces the default loading spinner with your custom layout resource. The custom view displays while messages are being fetched.

setEmptyView

Defines a custom view to be displayed when no messages are available.
cometchatMessageList.setEmptyView(R.layout.your_empty_view);
What this does: Replaces the default empty state with your custom layout resource. The custom view displays when the message list has no items.

setErrorView

Custom error state view displayed when fetching messages fails.
cometchatMessageList.setErrorView(R.layout.your_empty_view);
What this does: Replaces the default error state with your custom layout resource. The custom view displays when the component encounters an error during message fetching.

setTextFormatters

Assigns the list of text formatters. If the provided list is not null, it sets the list. Otherwise, it assigns the default text formatters retrieved from the data source. To configure the existing Mentions look and feel check out MentionsFormatter Guide.
themes.xml
<style name="CustomIncomingMessageBubbleMentionStyle" parent="CometChatIncomingBubbleMentionsStyle">
    <item name="cometchatMentionTextAppearance">?attr/cometchatTextAppearanceBodyRegular</item>
    <item name="cometchatMentionTextColor">#D6409F</item>
    <item name="cometchatMentionBackgroundColor">#D6409F</item>
    <item name="cometchatSelfMentionTextColor">#30A46C</item>
    <item name="cometchatSelfMentionTextAppearance">?attr/cometchatTextAppearanceBodyRegular</item>
    <item name="cometchatSelfMentionBackgroundColor">#30A46C</item>
</style>

<style name="CustomOutgoingMessageBubbleMentionStyle" parent="CometChatOutgoingBubbleMentionsStyle">
    <item name="cometchatMentionTextAppearance">?attr/cometchatTextAppearanceBodyRegular</item>
    <item name="cometchatMentionTextColor">#FFFFFF</item>
    <item name="cometchatMentionBackgroundColor">#F9F8FD</item>
    <item name="cometchatSelfMentionTextColor">#30A46C</item>
    <item name="cometchatSelfMentionTextAppearance">?attr/cometchatTextAppearanceBodyRegular</item>
    <item name="cometchatSelfMentionBackgroundColor">#30A46C</item>
</style>
What this does: Defines custom mention styles for incoming and outgoing message bubbles. Incoming mentions appear in pink (#D6409F) and outgoing mentions appear in white (#FFFFFF), both with green self-mentions (#30A46C).
// Initialize CometChatMentionsFormatter
CometChatMentionsFormatter mentionFormatter = new CometChatMentionsFormatter(context);

//set style to customize bubble mention text
mentionFormatter.setOutgoingBubbleMentionTextStyle(context, R.style.CustomOutgoingMessageBubbleMentionStyle);

mentionFormatter.setIncomingBubbleMentionTextStyle(context, R.style.CustomIncomingMessageBubbleMentionStyle);

// This can be passed as an array of formatter in CometChatMessageList by using setTextFormatters method.
List<CometChatTextFormatter> textFormatters = new ArrayList<>();
textFormatters.add(mentionFormatter);
messageList.setTextFormatters(textFormatters);
What this does: Creates a CometChatMentionsFormatter, applies custom outgoing and incoming mention styles, adds it to a list of text formatters, and passes that list to the message list component. Mentions in message bubbles render with the custom colors.

setHeaderView

Sets a custom header view for the message list. The header displays at the top of the message list.
cometChatMessageList.setHeaderView(view);
What this does: Sets a custom View as the header of the message list. Pass any view (e.g., a toolbar with action buttons) to display above the messages.
custom_header_layout.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:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="#EDEAFA"
    android:orientation="horizontal">

    <com.google.android.material.card.MaterialCardView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="@dimen/cometchat_margin_4"
        android:layout_marginTop="@dimen/cometchat_margin_1"
        android:layout_marginBottom="@dimen/cometchat_margin_1"
        android:elevation="0dp"
        app:cardCornerRadius="@dimen/cometchat_radius_max"
        app:cardElevation="0dp"
        app:strokeColor="?attr/cometchatStrokeColorLight"
        app:strokeWidth="1dp">

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

            <ImageView
                android:layout_width="20dp"
                android:layout_height="@dimen/cometchat_20dp"
                android:src="@drawable/cometchat_ic_file_upload"
                app:tint="?attr/cometchatPrimaryColor" />

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginStart="@dimen/cometchat_margin_1"
                android:text="Notes"
                android:textAppearance="?attr/cometchatTextAppearanceCaption1Regular"
                android:textColor="?attr/cometchatPrimaryColor" />
        </LinearLayout>
    </com.google.android.material.card.MaterialCardView>

    <com.google.android.material.card.MaterialCardView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="@dimen/cometchat_margin_4"
        android:layout_marginTop="@dimen/cometchat_margin_1"
        android:layout_marginBottom="@dimen/cometchat_margin_1"
        android:elevation="0dp"
        app:cardCornerRadius="@dimen/cometchat_radius_max"
        app:cardElevation="0dp"
        app:strokeColor="?attr/cometchatStrokeColorLight"
        app:strokeWidth="1dp">

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

            <ImageView
                android:layout_width="20dp"
                android:layout_height="@dimen/cometchat_20dp"
                android:src="@drawable/src_icons_pin"
                app:tint="?attr/cometchatPrimaryColor" />

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginStart="@dimen/cometchat_margin_1"
                android:text="Pinned Messages"
                android:textAppearance="?attr/cometchatTextAppearanceCaption1Regular"
                android:textColor="?attr/cometchatPrimaryColor" />
        </LinearLayout>
    </com.google.android.material.card.MaterialCardView>

    <com.google.android.material.card.MaterialCardView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="@dimen/cometchat_margin_4"
        android:layout_marginTop="@dimen/cometchat_margin_1"
        android:layout_marginBottom="@dimen/cometchat_margin_1"
        android:elevation="0dp"
        app:cardCornerRadius="@dimen/cometchat_radius_max"
        app:cardElevation="0dp"
        app:strokeColor="?attr/cometchatStrokeColorLight"
        app:strokeWidth="1dp">

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

            <ImageView
                android:layout_width="20dp"
                android:layout_height="@dimen/cometchat_20dp"
                android:src="@drawable/cometchat_link_file_icon"
                app:tint="?attr/cometchatPrimaryColor" />

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginStart="@dimen/cometchat_margin_1"
                android:text="Saved Links"
                android:textAppearance="?attr/cometchatTextAppearanceCaption1Regular"
                android:textColor="?attr/cometchatPrimaryColor" />
        </LinearLayout>
    </com.google.android.material.card.MaterialCardView>

</LinearLayout>
What this does: Defines a custom header layout with three pill-shaped buttons: “Notes”, “Pinned Messages”, and “Saved Links”. Each button uses a MaterialCardView with an icon and label styled with the primary color.
cometChatMessageList.setHeaderView(View.inflate(getContext(), R.layout.custom_header_layout, null));
What this does: Inflates the custom_header_layout.xml and sets it as the header view of the message list. The three pill buttons display above the messages.

setFooterView

Sets a custom footer view for the message list. The footer displays at the bottom of the message list.
cometChatMessageList.setFooterView(view);
What this does: Sets a custom View as the footer of the message list. Pass any view (e.g., quick reply buttons, typing indicators, or a disclaimer) to display below the messages.
custom_footer_layout.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:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="#EDEAFA"
    android:orientation="horizontal">

    <com.google.android.material.card.MaterialCardView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="@dimen/cometchat_margin_4"
        android:layout_marginTop="@dimen/cometchat_margin_1"
        android:layout_marginBottom="@dimen/cometchat_margin_1"
        android:elevation="0dp"
        app:cardCornerRadius="@dimen/cometchat_radius_max"
        app:cardElevation="0dp"
        app:strokeColor="?attr/cometchatStrokeColorLight"
        app:strokeWidth="1dp">

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

            <ImageView
                android:layout_width="20dp"
                android:layout_height="@dimen/cometchat_20dp"
                android:src="@drawable/cometchat_ic_file_upload"
                app:tint="?attr/cometchatPrimaryColor" />

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginStart="@dimen/cometchat_margin_1"
                android:text="Notes"
                android:textAppearance="?attr/cometchatTextAppearanceCaption1Regular"
                android:textColor="?attr/cometchatPrimaryColor" />
        </LinearLayout>
    </com.google.android.material.card.MaterialCardView>

    <com.google.android.material.card.MaterialCardView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="@dimen/cometchat_margin_4"
        android:layout_marginTop="@dimen/cometchat_margin_1"
        android:layout_marginBottom="@dimen/cometchat_margin_1"
        android:elevation="0dp"
        app:cardCornerRadius="@dimen/cometchat_radius_max"
        app:cardElevation="0dp"
        app:strokeColor="?attr/cometchatStrokeColorLight"
        app:strokeWidth="1dp">

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

            <ImageView
                android:layout_width="20dp"
                android:layout_height="@dimen/cometchat_20dp"
                android:src="@drawable/src_icons_pin"
                app:tint="?attr/cometchatPrimaryColor" />

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginStart="@dimen/cometchat_margin_1"
                android:text="Pinned Messages"
                android:textAppearance="?attr/cometchatTextAppearanceCaption1Regular"
                android:textColor="?attr/cometchatPrimaryColor" />
        </LinearLayout>
    </com.google.android.material.card.MaterialCardView>

    <com.google.android.material.card.MaterialCardView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="@dimen/cometchat_margin_4"
        android:layout_marginTop="@dimen/cometchat_margin_1"
        android:layout_marginBottom="@dimen/cometchat_margin_1"
        android:elevation="0dp"
        app:cardCornerRadius="@dimen/cometchat_radius_max"
        app:cardElevation="0dp"
        app:strokeColor="?attr/cometchatStrokeColorLight"
        app:strokeWidth="1dp">

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

            <ImageView
                android:layout_width="20dp"
                android:layout_height="@dimen/cometchat_20dp"
                android:src="@drawable/cometchat_link_file_icon"
                app:tint="?attr/cometchatPrimaryColor" />

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginStart="@dimen/cometchat_margin_1"
                android:text="Saved Links"
                android:textAppearance="?attr/cometchatTextAppearanceCaption1Regular"
                android:textColor="?attr/cometchatPrimaryColor" />
        </LinearLayout>
    </com.google.android.material.card.MaterialCardView>

</LinearLayout>
What this does: Defines a custom footer layout with three pill-shaped buttons: “Notes”, “Pinned Messages”, and “Saved Links”. Each button uses a MaterialCardView with an icon and label styled with the primary color.
cometChatMessageList.setFooterView(View.inflate(getContext(), R.layout.custom_footer_layout, null));
What this does: Inflates the custom_footer_layout.xml and sets it as the footer view of the message list. The three pill buttons display below the messages.
  • Verify: After setting any advanced view, confirm the custom view renders in the correct position within the message list, and the data binding populates correctly.

Customization matrix

What you want to changeWhereProperty/APIExample
Outgoing message bubble backgroundthemes.xmlCometChatMessageListStyle with cometchatMessageListOutgoingMessageBubbleStyle<item name="cometchatMessageBubbleBackgroundColor">#F76808</item>
Message list background colorthemes.xmlCometChatMessageListStyle with cometchatMessageListBackgroundColor<item name="cometchatMessageListBackgroundColor">#FEEDE1</item>
Apply a custom styleActivity/FragmentsetStyle(int styleRes)cometChatMessageList.setStyle(R.style.CustomCometChatMessageListStyle);
Set user for messagesActivity/FragmentsetUser(User).setUser(user);
Set group for messagesActivity/FragmentsetGroup(Group).setGroup(Group);
Message alignmentActivity/FragmentsetAlignment(UIKitConstants.MessageListAlignment).setAlignment(UIKitConstants.MessageListAlignment);
Error state visibilityActivity/FragmentsetErrorStateVisibility(int).setErrorStateVisibility(View.GONE);
Incoming/outgoing message soundActivity/FragmentdisableSoundForMessages(boolean).disableSoundForMessages(false);
Custom message soundActivity/FragmentsetCustomSoundForMessages(int).setCustomSoundForMessages(@RawRes resource);
Avatar visibilityActivity/FragmentsetAvatarVisibility(int).setAvatarVisibility(View.GONE);
Scroll to bottom on new messageActivity/FragmentscrollToBottomOnNewMessage(boolean).scrollToBottomOnNewMessage(true);
Read/delivered receipts visibilityActivity/FragmentsetReceiptsVisibility(int).setReceiptsVisibility(View.GONE);
Quick reactions listActivity/FragmentsetQuickReactions(List).setQuickReactions(Arrays.asList("👻","😈","🙀","🤡","❤️");
Sticky date visibilityActivity/FragmentsetStickyDateVisibility(int).setStickyDateVisibility(View.GONE);
Thread reply option visibilityActivity/FragmentreplyInThreadOptionVisibility(int).replyInThreadOptionVisibility(View.GONE);
Translate option visibilityActivity/FragmenttranslateMessageOptionVisibility(int).translateMessageOptionVisibility(View.GONE);
Edit option visibilityActivity/FragmenteditMessageOptionVisibility(int).editMessageOptionVisibility(View.GONE);
Delete option visibilityActivity/FragmentdeleteMessageOptionVisibility(int).deleteMessageOptionVisibility(View.GONE);
Reaction option visibilityActivity/FragmentsetMessageReactionOptionVisibility(int).setMessageReactionOptionVisibility(View.GONE);
Private message option visibilityActivity/FragmentmessagePrivatelyOptionVisibility(int).messagePrivatelyOptionVisibility(View.GONE);
Copy option visibilityActivity/FragmentcopyMessageOptionVisibility(int).copyMessageOptionVisibility(View.GONE);
Message info option visibilityActivity/FragmentmessageInfoOptionVisibility(int).messageInfoOptionVisibility(View.GONE);
Group action message visibilityActivity/FragmentgroupActionMessageVisibility(int).groupActionMessageVisibility(View.GONE);
Conversation startersActivity/FragmentenableConversationStarters(boolean).enableConversationStarters(true);
Smart repliesActivity/FragmentenableSmartReplies(boolean).enableSmartReplies(true);
Smart replies keywordsActivity/FragmentsetAISmartRepliesKeywords(List).setAISmartRepliesKeywords(Arrays.asList("hello", "hi"));
Smart replies delayActivity/FragmentsmartRepliesDelayDuration(int).smartRepliesDelayDuration(5000);
Date/time formattingActivity/FragmentsetDateTimeFormatter(DateTimeFormatterCallback)See setDateTimeFormatter code above
Sticky date formatActivity/FragmentsetDateFormat(SimpleDateFormat)messageList.setDateFormat(new SimpleDateFormat("MMM dd, yyyy", Locale.getDefault()));
Message bubble time formatActivity/FragmentsetTimeFormat(SimpleDateFormat)messageList.setTimeFormat(new SimpleDateFormat("hh:mm a", Locale.getDefault()));
Loading viewActivity/FragmentsetLoadingView(int)cometchatMessageList.setLoadingView(R.layout.your_loading_view);
Empty viewActivity/FragmentsetEmptyView(int)cometchatMessageList.setEmptyView(R.layout.your_empty_view);
Error viewActivity/FragmentsetErrorView(int)cometchatMessageList.setErrorView(R.layout.your_empty_view);
Header viewActivity/FragmentsetHeaderView(View)cometChatMessageList.setHeaderView(view);
Footer viewActivity/FragmentsetFooterView(View)cometChatMessageList.setFooterView(view);
Text formatters (mentions)Activity/FragmentsetTextFormatters(List<CometChatTextFormatter>)See setTextFormatters code above
Refresh styleActivity/FragmentrefreshStyle().refreshStyle();
Generate conversation summaryActivity/FragmentgenerateConversationSummary().generateConversationSummary();
Filter messagesActivity/FragmentsetMessagesRequestBuilder(MessagesRequestBuilder)See Filters code above

Common pitfalls & fixes

PitfallFix
Component does not renderEnsure CometChatUIKit.init() is called and awaited before using any UI Kit component. If init() has not completed, the component will not load data.
Message list shows only loading indicatorYou must call .setUser(user) or .setGroup(group) on the CometChatMessageList instance. Without a User or Group object, the component cannot fetch messages.
Messages not appearing for the correct conversationVerify that the User or Group object passed to setUser() or setGroup() has the correct UID or GUID. The component fetches messages for the specified entity only.
Custom style not visibleVerify the style parent is CometChatMessageListStyle and that you call setStyle(R.style.YourStyle) on the component instance.
Filters not appliedEnsure you call setMessagesRequestBuilder(builder) on the CometChatMessageList instance after creating and configuring the builder. Note that UID, GUID, types, and categories are always altered inside the message list.
setOnThreadRepliesClick not firingVerify that threaded messages exist in the conversation. The callback only fires when a user taps a message bubble that has thread replies.
Reactions not responding to custom click handlersEnsure you set the reaction callbacks (setOnReactionClick, setOnReactionLongClick, setOnAddMoreReactionsClick) before the component loads messages.
Smart replies not appearingEnsure enableSmartReplies(true) is called. If you set smartRepliesKeywords, verify that incoming messages contain at least one of the specified keywords.
Sound still plays after disableSoundForMessages(true)Ensure you call disableSoundForMessages(true) before the component starts loading. If called after data is already loaded, it may not take effect for existing notifications.

FAQ

Q: How do I display messages for a group instead of a user? A: Call .setGroup(group) with a Group object instead of .setUser(user). The component fetches and displays messages for the specified group conversation. Q: How do I filter messages by a search keyword? A: Create a MessagesRequest.MessagesRequestBuilder, call .setSearchKeyword("your keyword"), and pass it to setMessagesRequestBuilder. Note that UID, GUID, types, and categories are always overridden internally by the message list. Q: How do I customize the date format for sticky date separators? A: Call messageList.setDateFormat(new SimpleDateFormat("MMM dd, yyyy", Locale.getDefault())) to set a custom date format for the sticky date headers. Q: Does the MessageList component emit any events? A: No. The MessageList component does not emit any events of its own. If you need to listen for message-level events, use the CometChat SDK’s message listeners directly. Q: How do I add a custom header or footer to the message list? A: Call cometChatMessageList.setHeaderView(view) to add a custom view above the messages, or cometChatMessageList.setFooterView(view) to add one below the messages. Pass any inflated View object.

Next steps