Skip to main content
CometChatMessageHeader displays User or Group details in the toolbar, including a typing indicator and a back navigation button.

When to use this

  • You need a header bar that shows the name, avatar, and status of the user or group in a chat screen.
  • You want to display a typing indicator when the other party is typing.
  • You need back navigation from the message screen to the previous screen.
  • You want to show voice and video call buttons in the header.
  • You want to replace default header elements (subtitle, leading view, trailing view) with custom layouts.

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.
  • A layout XML file or Activity/Fragment where you will place the component.

Quick start

  1. Open your layout XML file (e.g., your_layout.xml).
  2. Add the CometChatMessageHeader XML element:
your_layout.xml
<com.cometchat.chatuikit.messageheader.CometChatMessageHeader
                android:id="@+id/header"
                android:layout_width="match_parent"
                android:layout_height="56dp" />
What this does: Adds the CometChatMessageHeader component to your layout with a fixed height of 56dp. It fills the available width and renders the header bar.
  1. In your Activity or Fragment, get a reference to the component and set a User or Group object:
YourActivity.java
cometchatMessageHeader.setUser(user);
What this does: Passes a User object to the header so it displays that user’s name, avatar, and status.
  1. Build and run your app.
  2. Verify that the header displays the user or group name, avatar, and status information.

Core concepts

  • CometChatMessageHeader: The main component class that renders user or group details in a toolbar. It is added via XML layout.
  • Actions: Callbacks such as setOnBackPressListener and setOnError that let you respond to user interactions.
  • Filters: The MessageHeader component does not expose any filters.
  • Events: The MessageHeader component does not produce any events.
  • Style: XML theme styles (parent CometChatMessageHeaderStyle) applied via setStyle() to customize colors, fonts, and sub-component styles.
  • Advanced views: Methods like setLeadingView, setSubtitleView, setTrailingView, setItemView, and setAuxiliaryButtonView 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 back-press and errors.
  • Where: Activity or Fragment where you hold a reference to CometChatMessageHeader (e.g., cometchatMessageHeader).
  • Applies to: CometChatMessageHeader.
  • Default behavior: Predefined actions execute automatically (e.g., pressing back navigates to the previous activity).
  • Override: Call the corresponding setter method to replace the default behavior with your own logic.

setOnError

Listens for any errors that occur in the component. This does not change the component’s behavior.
YourActivity.java
cometchatMessageHeader.setOnError(cometchatException -> {

    });
What this does: Registers an error listener. If the component encounters an error, your callback receives the CometChatException.

setOnBackPressListener

Triggered when the user presses the back button in the app bar. By default, it navigates to the previous activity.
YourActivity.java
cometchatMessageHeader.setOnBackPressListener(() -> {
            
    });
What this does: Overrides the default back-press navigation. When the user taps the back button, your custom logic runs instead.
  • Verify: After setting an action callback, trigger the corresponding user interaction (back-press) and confirm your custom logic executes instead of the default behavior.

Style

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

    <style name="CustomMessageHeaderStyle" parent="CometChatMessageHeaderStyle">
        <item name="cometchatMessageHeaderTitleTextColor">#F76808</item>
        <item name="cometchatMessageHeaderAvatarStyle">@style/CustomAvatarStyle</item>
        <item name="cometchatMessageHeaderCallButtonsStyle">@style/CustomCallButtonStyle</item>
    </style>
What this does: Defines two custom styles: CustomCallButtonStyle sets the video and voice call icon tints to #F76808; CustomMessageHeaderStyle sets the title text color to #F76808 and applies custom avatar and call button sub-styles to the message header component.
cometchatMessageHeader.setStyle(R.style.CustomMessageHeaderStyle);
What this does: Applies the CustomMessageHeaderStyle theme to the CometChatMessageHeader component, changing the title text color, avatar style, and call button icon tints.
To know more such attributes, visit the attributes file.
  • Verify: The header title text displays in orange (#F76808), and the voice and video call icons display with orange tint (#F76808).

Functionality

What you’re changing: Small functional customizations such as toggling visibility of UI elements and setting the user or group object.
  • Where: Activity or Fragment where you hold a reference to CometChatMessageHeader.
  • Applies to: CometChatMessageHeader.
  • Default behavior: All UI elements are visible with default settings.
  • Override: Call the corresponding method on the component instance.
MethodsDescriptionCode
setUserPasses a user object to display that user’s header details. This is a required property for the component to function..setUser(user)
setGroupPasses a group object to display that group’s header details. This is a required property for the component to function..setGroup(Group)
setBackButtonVisibilityToggles visibility for the back button.setBackButtonVisibility(View.GONE)
setUserStatusVisibilityToggles visibility for the user’s online/offline status.setUserStatusVisibility(View.VISIBLE)
setVideoCallButtonVisibilityToggles visibility for the video call button.setVideoCallButtonVisibility(View.VISIBLE)
setVoiceCallButtonVisibilityToggles visibility for the voice call button.setVoiceCallButtonVisibility(View.VISIBLE)
  • Verify: After calling a visibility method, confirm the corresponding UI element is shown or hidden. After calling setUser(user), confirm the header displays that user’s name and avatar.

Advanced views

What you’re changing: The default UI elements of the message header, including date formatting, auxiliary buttons, menu options, the entire header layout, subtitle, leading view, and trailing view.
  • Where: Activity or Fragment where you hold a reference to CometChatMessageHeader.
  • Applies to: CometChatMessageHeader.
  • Default behavior: The component renders its built-in views for each part of the header.
  • Override: Call the corresponding setter method and provide a custom view or callback.

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;


cometchatMessageHeader.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 the message header. 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.

setAuxiliaryButtonView

Allows adding a custom button or additional action next to the title or trailing section.
YourActivity.java
cometchatMessageHeader.setAuxiliaryButtonView((context, user, group) -> {
            
    });
What this does: Registers a callback that returns a custom View to display as an auxiliary button in the header. The callback receives the current Context, User, and Group objects so you can customize the view based on the conversation.

setItemView

Replaces the entire default header with a fully customized layout.
YourActivity.java
cometchatMessageHeader.setItemView((context, user, group) -> {
            
    });
What this does: Registers a callback that returns a custom View to replace the entire default message header layout. The callback receives the current Context, User, and Group objects.
Create a custom_message_header.xml layout file:
custom_message_header.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"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/parent_layout"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:gravity="center_vertical"
    android:padding="10dp">

    <ImageView
        android:id="@+id/iv_message_header_back"
        android:layout_width="@dimen/cometchat_24dp"
        android:layout_height="@dimen/cometchat_24dp"
        android:layout_gravity="center_vertical"
        android:src="@drawable/cometchat_ic_back"
        app:tint="@color/black"
        tools:ignore="ContentDescription" />

    <androidx.constraintlayout.widget.ConstraintLayout
        android:id="@+id/message_header_avatar_layout"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="@dimen/cometchat_margin_2"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintStart_toEndOf="@+id/message_header_back_icon_layout"
        app:layout_constraintTop_toTopOf="parent">

        <com.cometchat.chatuikit.shared.views.avatar.CometChatAvatar
            android:id="@+id/message_header_avatar_view"
            android:layout_width="@dimen/cometchat_40dp"
            android:layout_height="@dimen/cometchat_40dp"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

    </androidx.constraintlayout.widget.ConstraintLayout>

    <LinearLayout
        android:id="@+id/message_header_center_layout"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginStart="@dimen/cometchat_margin_2"
        android:layout_marginEnd="@dimen/cometchat_padding_3"
        android:layout_weight="1"
        android:gravity="center_vertical"
        android:orientation="vertical"
        app:layout_constraintBottom_toBottomOf="parent">

        <TextView
            android:id="@+id/tv_message_header_name"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:ellipsize="end"
            android:gravity="start"
            android:maxLines="1"
            android:text="hvfcghv"
            android:textAppearance="?attr/cometchatTextAppearanceHeading4Medium"
            android:textColor="?attr/cometchatTextColorPrimary" />


        <TextView
            android:id="@+id/tv_message_header_subtitle"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:ellipsize="marquee"
            android:focusable="true"
            android:focusableInTouchMode="true"
            android:gravity="center_vertical"
            android:marqueeRepeatLimit="1"
            android:minHeight="@dimen/cometchat_19dp"
            android:scrollHorizontally="true"
            android:singleLine="true"
            android:textAppearance="?attr/cometchatTextAppearanceCaption1Regular"
            android:textColor="?attr/cometchatTextColorSecondary" />


    </LinearLayout>

    <LinearLayout
        android:id="@+id/end_container"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:gravity="center_vertical"
        android:orientation="horizontal"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toTopOf="parent">

        <com.cometchat.chatuikit.calls.callbutton.CometChatCallButtons
            android:id="@+id/call_button"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginEnd="@dimen/cometchat_margin_2" />
        
    </LinearLayout>


</LinearLayout>
What this does: Defines a custom message header layout with a back button, avatar, title and subtitle text views, and call buttons. This layout replaces the entire default header when inflated in setItemView.
Inflate the XML and initialize the views:
cometchatMessageHeader.setItemView((context, user, group) -> {
            View view = LayoutInflater.from(context).inflate(R.layout.custom_message_header, null);
            LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,
                                                                             LinearLayout.LayoutParams.WRAP_CONTENT);
            CometChatAvatar avatar = view.findViewById(R.id.message_header_avatar_view);
            TextView titleText = view.findViewById(R.id.tv_message_header_name);
            TextView subtitleText = view.findViewById(R.id.tv_message_header_subtitle);
            CometChatCallButtons cometChatCallButtons = view.findViewById(R.id.call_button);

            if (user != null) {
                avatar.setAvatar(user.getName(), user.getAvatar());
                titleText.setText(user.getName());
                subtitleText.setText(user.getStatus());
                cometChatCallButtons.setUser(user);
            } else {
                avatar.setAvatar(group.getName(), group.getIcon());
                titleText.setText(group.getName());
                subtitleText.setText(group.getMembersCount() + " members");
                cometChatCallButtons.setGroup(group);
            }
            view.setLayoutParams(params);
            return view;
        });
What this does: Inflates the custom_message_header.xml layout and populates it with the user’s or group’s avatar, name, and status/member count. If the conversation is with a user, it sets the user’s status as the subtitle and configures call buttons for that user. If the conversation is with a group, it sets the member count as the subtitle and configures call buttons for that group.

setSubtitleView

Allows customizing the subtitle view, used for status messages or additional details.
YourActivity.java
cometchatMessageHeader.setSubtitleView((context, user, group) -> {
            
    });
What this does: Registers a callback that returns a custom View for the subtitle area of the header. The callback receives the current Context, User, and Group objects so you can customize the subtitle based on the conversation.
YourActivity.java
cometChatMessageHeader.setSubtitleView((context, user, group) -> {
            TextView textView = new TextView(context);
            if(user!=null) {
                textView.setText(user.getStatus());
            }else if(group!=null) {
                textView.setText(group.getMembersCount() > 1 ? group.getMembersCount() + " members" : group.getMembersCount() + " member" + " • " + group.getDescription());
            }
            return textView;
        });
What this does: Creates a TextView and sets its text to the user’s status (for user conversations) or the group’s member count and description (for group conversations). If the group has more than 1 member, it shows “X members”; otherwise it shows “1 member • [description]”.

setLeadingView

Defines a custom leading view, used for the receiver’s profile picture or avatar.
YourActivity.java
cometchatMessageHeader.setLeadingView((context, user, group) -> {
            
    });
What this does: Registers a callback that returns a custom View for the leading (left) area of the header. The callback receives the current Context, User, and Group objects.
Create a header_leading_view.xml layout file:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="@dimen/cometchat_45dp"
    android:layout_height="@dimen/cometchat_45dp"
    android:orientation="vertical">

    <com.cometchat.chatuikit.shared.views.avatar.CometChatAvatar
        android:id="@+id/avatar"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

    <View
        android:id="@+id/batch_view"
        android:layout_width="match_parent"
        android:layout_height="@dimen/cometchat_12dp"
        android:layout_alignParentBottom="true"
        android:visibility="gone"
        android:background="@drawable/admin_batch" />

</RelativeLayout>
What this does: Defines a custom leading view layout with a CometChatAvatar and a hidden admin badge view. The badge becomes visible when the user has an “admin” role or the group owner matches the logged-in user.
Inflate the XML and initialize the views:
cometChatMessageHeader.setLeadingView(new Function3<Context, User, Group, View>() {
            @Override
            public View apply(Context context, User user, Group group) {
                View view = LayoutInflater.from(context).inflate(R.layout.header_leading_view, null);
                CometChatAvatar avatar = view.findViewById(R.id.avatar);
                View view1 = view.findViewById(R.id.batch_view);
                if (user != null) {
                    avatar.setAvatar(user.getName(), user.getAvatar());
                    if ("admin".equals(user.getRole())) {
                        view1.setVisibility(View.VISIBLE);
                    }
                } else {
                    avatar.setAvatar(group.getName(), group.getIcon());
                    if (group.getOwner().equals(CometChatUIKit.getLoggedInUser().getUid())) {
                        view1.setVisibility(View.VISIBLE);
                    }
                }

                LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(Utils.convertDpToPx(context, 45), Utils.convertDpToPx(context, 45));
                view.setLayoutParams(params);
                return view;
            }
        });
What this does: Inflates the header_leading_view.xml layout and sets the avatar image from the user or group. If the user has an “admin” role, or if the logged-in user is the group owner, the admin badge view becomes visible. The view is sized to 45dp × 45dp.

setTrailingView

Customizes the trailing (end) view of the header, used for action buttons or indicators.
YourActivity.java
cometchatMessageHeader.setTrailingView((context, user, group) -> {
            
    });
What this does: Registers a callback that returns a custom View for the trailing (right) area of the header. The callback receives the current Context, User, and Group objects.
cometChatMessageHeader.setTrailingView((context, user, group) -> {
            ImageView imageView = new ImageView(context);
            imageView.setImageResource(R.drawable.save_icon);
            LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(Utils.convertDpToPx(context, 24), Utils.convertDpToPx(context, 24));
            params.leftMargin = Utils.convertDpToPx(context, 16);
            imageView.setLayoutParams(params);
            return imageView;
        });
What this does: Creates an ImageView with a save icon drawable, sizes it to 24dp × 24dp with a 16dp left margin, and returns it as the trailing view in the header.
  • Verify: After setting any advanced view, confirm the custom view renders in the correct position within the message header, and the data binding populates correctly for the user or group.

Customization matrix

What you want to changeWhereProperty/APIExample
Title text colorthemes.xmlCometChatMessageHeaderStyle with cometchatMessageHeaderTitleTextColor<item name="cometchatMessageHeaderTitleTextColor">#F76808</item>
Avatar stylethemes.xmlCometChatMessageHeaderStyle with cometchatMessageHeaderAvatarStyle<item name="cometchatMessageHeaderAvatarStyle">@style/CustomAvatarStyle</item>
Call button icon tintsthemes.xmlCometChatCallButtonsStyle with cometchatCallButtonsVideoCallIconTint / cometchatCallButtonsVoiceCallIconTint<item name="cometchatCallButtonsVideoCallIconTint">#F76808</item>
Apply a custom styleActivity/FragmentsetStyle(int styleRes)cometchatMessageHeader.setStyle(R.style.CustomMessageHeaderStyle);
User objectActivity/FragmentsetUser(User).setUser(user)
Group objectActivity/FragmentsetGroup(Group).setGroup(Group)
Back button visibilityActivity/FragmentsetBackButtonVisibility(int).setBackButtonVisibility(View.GONE)
User status visibilityActivity/FragmentsetUserStatusVisibility(int).setUserStatusVisibility(View.VISIBLE)
Video call button visibilityActivity/FragmentsetVideoCallButtonVisibility(int).setVideoCallButtonVisibility(View.VISIBLE)
Voice call button visibilityActivity/FragmentsetVoiceCallButtonVisibility(int).setVoiceCallButtonVisibility(View.VISIBLE)
Date/time formattingActivity/FragmentsetDateTimeFormatter(DateTimeFormatterCallback)See setDateTimeFormatter code above
Auxiliary button viewActivity/FragmentsetAuxiliaryButtonView(Function3)See setAuxiliaryButtonView code above
Entire header layoutActivity/FragmentsetItemView(Function3)See setItemView code above
Subtitle viewActivity/FragmentsetSubtitleView(Function3)See setSubtitleView code above
Leading view (avatar area)Activity/FragmentsetLeadingView(Function3)See setLeadingView code above
Trailing viewActivity/FragmentsetTrailingView(Function3)See setTrailingView 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.
Header shows no user or group detailsEnsure you call setUser(user) or setGroup(group) on the CometChatMessageHeader instance. The component requires one of these to display header details.
Back button not visibleCall setBackButtonVisibility(View.VISIBLE) on the component instance. The back button visibility may default to hidden depending on your layout.
Custom style not appliedVerify the style parent is CometChatMessageHeaderStyle and that you call setStyle(R.style.YourStyle) on the component instance.
Call buttons not visibleEnsure setVideoCallButtonVisibility(View.VISIBLE) and setVoiceCallButtonVisibility(View.VISIBLE) are called. If the calling feature is not enabled, the buttons may not appear.
setOnBackPressListener not firingEnsure the back button is visible by calling setBackButtonVisibility(View.VISIBLE). If the back button is hidden, the listener will not trigger.
Custom subtitle view not renderingEnsure your setSubtitleView callback returns a valid View object. If the callback returns null, the default subtitle is used.

FAQ

Q: Do I need to pass both a User and a Group object? A: No. Pass either a User object using setUser(user) or a Group object using setGroup(group). The component displays details for whichever object is set. Q: How do I customize the call button icons in the header? A: Define a custom style with parent CometChatCallButtonsStyle in themes.xml, set cometchatCallButtonsVideoCallIconTint and cometchatCallButtonsVoiceCallIconTint, then reference it in your CometChatMessageHeaderStyle using cometchatMessageHeaderCallButtonsStyle. Q: Can I replace the entire header layout? A: Yes. Use setItemView to provide a Function3<Context, User, Group, View> callback that returns your custom layout. This replaces the entire default header. Q: Does the MessageHeader component emit any events? A: No. The MessageHeader component does not produce any events. Use action callbacks (setOnBackPressListener) to respond to user interactions.

Next steps