Skip to main content

Goal

By the end of this guide you will have a color button at the trailing end of the composer’s rich-text toolbar. The user selects some text, picks a color, and the text turns that color — in the composer while typing, and in the message bubble after it is sent. Android’s built-in RichTextFormat set covers bold, italic, underline, strikethrough, code, lists, blockquote and links — but not color. So the work splits into two pieces:
  1. Authoring — a button in the composer’s rich-text toolbar trailing slot that wraps the current selection in a color token through the ComposerInputController.
  2. Rendering — a CometChatTextFormatter that turns that token into colored text on every surface, and styles it live in the composer.
This guide builds color on top of the formatter base class. For the base class itself — tracking characters, suggestion lists, handlePreMessageSend — see the Text Formatter Base Class guide.

Prerequisites

  • Completed the Getting Started guide
  • A chat screen using CometChatMessageList and CometChatMessageComposer
  • Rich text formatting enabled on the composer — setEnableRichTextFormatting(true) / enableRichTextFormatting = true
The trailing slot lives inside the rich-text toolbar. It is not rendered when the toolbar is hidden or the rich-text editor is disabled, so the button disappears along with Bold and Italic.

Step 1: The Formatter

Extend CometChatTextFormatter. Our token is {color:#hex}…{/color} — plain text in the message body, which the formatter turns into colored text. Two details make it a rendering-only formatter rather than a suggestion one: a private-use tracking character ('\uE000') that a user can never type, and setDisableSuggestions(true). The formatter does two jobs:
  • prepare*Span() — strips the markers and applies the color on bubbles, conversation subtitles and reply/edit previews.
  • applyComposerSpans() (XML) / composerVisualTransformation() (Compose) — renders the token in place in the live input, so the user sees color while typing. Both are display-only: the token characters stay in the field, so they still go on the wire.
prepareComposerSpan() stays identity on purpose. Editing an existing message reads that text back into the input, so stripping the token there would drop the color from the composer and from the re-sent message.
The markers are hidden with a zero-width ReplacementSpan — it draws nothing and reports width 0, while leaving the characters in the Editable.File: ColorComposerSpans.kt
File: ColorFormatter.kt

Step 2: The Toolbar Button

The trailing slot hands your view a live ComposerInputController. The button reads selection, takes the selected substring out of text, and writes the token back with replaceSelection().
File: ColorToolbarButton.kt
A PopupMenu / DropdownMenu is safe here. An Android EditText keeps its selectionStart and selectionEnd when a popup takes focus, so the selection is still there when your handler runs.

Step 3: Wire It Into the Composer

Register the formatter on the composer and mount the button in the trailing slot.
Now: the user selects “world”, picks Red, and the word turns red in the composer while the {color:…} markers stay hidden. On send, the message text Hello {color:#E53935}world{/color} is stored on the message.

Step 4: Render It Everywhere the Message Appears

The token only becomes color on a surface that runs the formatter. Register it on every component where the message can show up.
Give each surface its own formatter instances. The built-in mentions formatter is stateful per rendered message, so sharing one list between the composer and the message list will cross-wire them.

How It Round-Trips

The markers never leave the message text — the composer only hides them, and the bubble’s prepare*Span() strips them at render time. That is what lets the color survive edit and reply: the composer repopulates with the stored token and renders it again.

Next Steps

Message Composer

The trailing-toolbar slot in detail

Text Formatter Base Class

Tracking characters, suggestion lists, and pre-send hooks

Mentions Formatter

Built-in @mention formatting with styled tokens

All Guides

Browse all feature and formatter guides