Skip to main content
Implement threaded replies in your Android chat app using CometChat’s UI Kit, enabling users to reply to specific messages in a focused sub-conversation.

Overview

Threaded replies allow users to respond directly to a specific message in one-on-one or group chats, improving context and readability:
  • Organizes related replies into a dedicated thread view.
  • Mirrors functionality in Slack, Discord, and WhatsApp.
  • Maintains clarity in active conversations.
Users tap a message → open thread screen → view parent message + replies → compose within thread.

Prerequisites

  • Android project in Android Studio.
  • CometChat Android UI Kit v6 (com.cometchat:chatuikit-kotlin or com.cometchat:chatuikit-jetpack) added to your build.gradle.
  • Valid CometChat App ID, Auth Key, and Region initialized.
  • <uses-permission android:name="android.permission.INTERNET"/> in AndroidManifest.xml.
  • Logged-in user via CometChatUIKit.login().
  • Existing MessagesActivity using CometChatMessageList.

Components

Integration Steps

Step 1: Add Thread Layout

Create res/layout/activity_thread_message.xml:
activity_thread_message.xml

Step 2: Set up ThreadMessageActivity

Initialize UI & handle blocked-user flows:

Step 3: Create ThreadMessageViewModel

Store parent message and expose via StateFlow:

Step 4: Hook Thread Entry from Message List

In your MessagesActivity, capture thread icon taps:

Implementation Flow

  1. User taps thread icon on a message.
  2. Intent launches ThreadMessageActivity with raw message JSON (or Compose navigation).
  3. ViewModel stores parent message and exposes via StateFlow.
  4. Header & MessageList render parent + replies.
  5. Composer sends new replies under the parent message.
  6. Live updates flow automatically via UI Kit.

Customization Options

  • Styling: Override theme attributes or call setter methods on views.
  • Header Height: threadHeader.setMaxHeight(...).
  • Hide Reactions: threadHeader.setReactionVisibility(View.GONE).

Filtering & Edge Cases

  • Group Membership: Verify membership before enabling composer.
  • Empty Thread: Show placeholder if no replies.
  • Blocked Users: Composer hidden; use unblock layout.

Blocked-User Handling

Group vs. User-Level Differences

Thread Subscription

Thread subscription gives users Slack-style control over thread noise: they can subscribe to a thread to be notified about its replies, or unsubscribe from one to mute it. Users are automatically subscribed when they start a thread, reply in one, or are @-mentioned in one — subscribing explicitly is how they opt in to a conversation they haven’t participated in yet. The UI Kit ships two surfaces for the same toggle, wired out of the box and kept in sync automatically:
  1. A Subscribe to thread / Unsubscribe from thread option in the message action sheet.
  2. A subscription bell on the thread view.

The Message Action Sheet Option

CometChatMessageList adds a Subscribe to thread / Unsubscribe from thread option to the long-press action sheet. The label reflects the current state, and the option appears on regular messages of every type (agent messages and moderation-blocked messages are excluded) — on a thread reply it targets the thread’s root message, so subscribing from anywhere in the thread works. To hide the option while keeping the rest of the feature:

The Thread Header Bell

CometChatThreadHeader renders a subscription bell as a trailing control on the reply-count bar. It flips optimistically on tap and reverts with a toast if the request fails.
The visibility can also be set in XML with the app:cometchatThreadSubscriptionVisibility attribute.

Hosting the Bell in Your Own Top Bar

Many apps (matching the CometChat sample apps and Figma) place the subscription bell in the thread screen’s top title bar rather than the reply-count row. In Compose, the bell is available as a standalone public composable — hide the header’s built-in one and host ThreadSubscriptionBell wherever you like:

Subscription Behavior

  • Optimistic with revert — both surfaces flip instantly on tap, keep one request in flight per thread, and revert with a toast if the server rejects the change. An offline tap fails visibly and reverts; nothing is queued.
  • Auto-subscribe on reply — sending a reply in a thread subscribes the user, and every surface flips to the subscribed state automatically.
  • Unsubscribing is not sticky — replying again, or being @-mentioned, re-subscribes the user.
  • Unknown state renders as unsubscribed — a message whose subscription state hasn’t been learned yet (for example, one that just arrived in real time) shows the enabled subscribe control, never a spinner.

Cross-Surface Sync

Both surfaces observe the UI Kit event bus, so toggling in one place updates the other without a refetch. If you build your own subscription control, emit and collect CometChatThreadEvent through CometChatEvents.threadEvents — see Events.

Notifications

Whether a subscribed thread actually produces a push notification is governed by the user’s notification preferences: the replies preference supports notifying only for threads the user is subscribed to (SUBSCRIBE_TO_SUBSCRIBED_THREADS). See Thread Subscription (SDK).

Summary / Feature Matrix

Next Steps & Further Reading

Thread Subscription (SDK)

The underlying APIs, including fetching the threads a user participates in to build a thread inbox.

Android Sample App (Kotlin)

Explore this feature in the CometChat SampleApp: GitHub → SampleApp