
Cometchat Android V5 Customization
- 5 installs
- 70 repo stars
- Updated June 23, 2026
- cometchat/cometchat-skills
Customizes CometChat Android v5 components beyond theming via custom message templates, DataSource decorators, ChatConfigurator, and event listeners.
About
This skill covers deeper CometChat v5 Android customization using custom message templates, the DataSource/DataSourceDecorator pattern, ChatConfigurator, and event listeners. A developer uses it to add custom message bubbles, custom option actions, filter conversations, or listen to message events.
- DataSource/DataSourceDecorator and ChatConfigurator patterns for behavior overrides
- Custom message templates, event listeners, and custom view slots
Cometchat Android V5 Customization by the numbers
- 5 all-time installs (skills.sh)
- Ranked #828 of 1,039 Mobile Development skills by installs in the Skillselion catalog
- Data as of Aug 5, 2026 (Skillselion catalog sync)
npx skills add https://github.com/cometchat/cometchat-skills --skill cometchat-android-v5-customizationAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 5 |
|---|---|
| repo stars | ★ 70 |
| Last updated | June 23, 2026 |
| Repository | cometchat/cometchat-skills ↗ |
What it does
Customizes CometChat Android v5 components beyond theming via custom message templates, DataSource decorators, ChatConfigurator, and event listeners.
Files
Companion skills: cometchat-android-v5-components provides the componentcatalog; cometchat-android-v5-theming covers visual styling;cometchat-android-v5-extensions covers the extension architecture.Purpose
This skill teaches how to customize CometChat components beyond what theming provides. It covers custom message templates, the DataSource/DataSourceDecorator pattern, ChatConfigurator, event listeners, and custom view slots.
---
Use this skill when
- "Customize the message list"
- "Add a custom message bubble"
- "Listen to message events"
- "Add a custom action to message options"
- "Filter conversations"
Do not use this skill when
- Changing colors/fonts → use
cometchat-android-v5-theming - Enabling a packaged feature → use
cometchat-android-v5-features - Setting up init/login → use
cometchat-android-v5-core
---
1. CometChatMessageTemplate
Templates define how message bubbles are rendered. Each template maps a message type + category to custom views.
Java:
CometChatMessageTemplate template = new CometChatMessageTemplate()
.setType(CometChatConstants.MESSAGE_TYPE_TEXT)
.setCategory(CometChatConstants.CATEGORY_MESSAGE)
.setContentView(new MessagesViewHolderListener() {
@Override
public View createView(Context context, CometChatMessageBubble messageBubble,
UIKitConstants.MessageBubbleAlignment alignment) {
// Return your custom view
return LayoutInflater.from(context).inflate(R.layout.custom_text_bubble, null);
}
@Override
public void bindView(Context context, View createdView, BaseMessage message,
UIKitConstants.MessageBubbleAlignment alignment,
RecyclerView.ViewHolder holder, List<BaseMessage> messageList,
int position) {
// Bind data to your custom view
TextView textView = createdView.findViewById(R.id.customText);
textView.setText(((TextMessage) message).getText());
}
})
.setOptions((context, baseMessage, group) -> {
// Return custom message options (long-press menu)
List<CometChatMessageOption> options = new ArrayList<>();
options.add(new CometChatMessageOption("custom_action", "Custom Action",
R.drawable.ic_custom, () -> { /* handle click */ }));
return options;
});
// Apply to message list
messageList.setTemplates(Collections.singletonList(template));Kotlin:
val template = CometChatMessageTemplate()
.setType(CometChatConstants.MESSAGE_TYPE_TEXT)
.setCategory(CometChatConstants.CATEGORY_MESSAGE)
.setContentView(object : MessagesViewHolderListener() {
override fun createView(context: Context, messageBubble: CometChatMessageBubble,
alignment: UIKitConstants.MessageBubbleAlignment): View {
return LayoutInflater.from(context).inflate(R.layout.custom_text_bubble, null)
}
override fun bindView(context: Context, createdView: View, message: BaseMessage,
alignment: UIKitConstants.MessageBubbleAlignment,
holder: RecyclerView.ViewHolder, messageList: List<BaseMessage>,
position: Int) {
val textView = createdView.findViewById<TextView>(R.id.customText)
textView.text = (message as TextMessage).text
}
})
.setOptions { context, baseMessage, group ->
listOf(CometChatMessageOption("custom_action", "Custom Action",
R.drawable.ic_custom) { /* handle click */ })
}
messageList.setTemplates(listOf(template))Template view slots
| Slot | Method | Description |
|---|---|---|
bubbleView | setBubbleView(MessagesViewHolderListener) | Entire message bubble |
headerView | setHeaderView(MessagesViewHolderListener) | Above the bubble |
contentView | setContentView(MessagesViewHolderListener) | Inside the bubble |
bottomView | setBottomView(MessagesViewHolderListener) | Below the content, inside bubble |
footerView | setFooterView(MessagesViewHolderListener) | Below the bubble |
statusInfoView | setStatusInfoView(MessagesViewHolderListener) | Status info area |
replyView | setReplyView(MessagesViewHolderListener) | Reply preview above bubble |
---
2. CometChatMessageOption
Custom actions in the message long-press menu.
Java:
CometChatMessageOption option = new CometChatMessageOption(
"bookmark", // unique ID
"Bookmark", // title
R.drawable.ic_bookmark, // icon
() -> { // onClick
// Handle bookmark action
}
);---
3. DataSource and DataSourceDecorator
The DataSource interface defines how messages are rendered and what options are available. DataSourceDecorator wraps an existing DataSource to add or modify behavior without replacing it.
Java:
public class CustomDataSource extends DataSourceDecorator {
public CustomDataSource(DataSource dataSource) {
super(dataSource);
}
@Override
public List<CometChatMessageOption> getTextMessageOptions(Context context,
BaseMessage baseMessage, Group group, AdditionParameter additionParameter) {
List<CometChatMessageOption> options = super.getTextMessageOptions(context,
baseMessage, group, additionParameter);
// Add custom option
options.add(new CometChatMessageOption("translate", "Translate",
R.drawable.ic_translate, () -> { /* translate */ }));
return options;
}
}Kotlin:
class CustomDataSource(dataSource: DataSource) : DataSourceDecorator(dataSource) {
override fun getTextMessageOptions(context: Context, baseMessage: BaseMessage,
group: Group?, additionParameter: AdditionParameter): List<CometChatMessageOption> {
val options = super.getTextMessageOptions(context, baseMessage, group, additionParameter).toMutableList()
options.add(CometChatMessageOption("translate", "Translate",
R.drawable.ic_translate) { /* translate */ })
return options
}
}Register via ChatConfigurator
Java:
ChatConfigurator.enable(dataSource -> new CustomDataSource(dataSource));Kotlin:
ChatConfigurator.enable { dataSource -> CustomDataSource(dataSource) }---
4. Event system
CometChat provides event classes for reacting to chat events. Register listeners with a unique tag.
CometChatMessageEvents
Java:
CometChatMessageEvents.addListener("unique-tag", new CometChatMessageEvents() {
@Override
public void ccMessageSent(BaseMessage baseMessage, int status) {
// Message sent
}
@Override
public void onTextMessageReceived(TextMessage textMessage) {
// Text message received
}
@Override
public void onMessageReactionAdded(ReactionEvent reactionEvent) {
// Reaction added
}
});
// Remove when done
CometChatMessageEvents.removeListener("unique-tag");Kotlin:
CometChatMessageEvents.addListener("unique-tag", object : CometChatMessageEvents() {
override fun ccMessageSent(baseMessage: BaseMessage, status: Int) {
// Message sent
}
override fun onTextMessageReceived(textMessage: TextMessage) {
// Text message received
}
override fun onMessageReactionAdded(reactionEvent: ReactionEvent) {
// Reaction added
}
})
// Remove when done
CometChatMessageEvents.removeListener("unique-tag")CometChatUserEvents
CometChatUserEvents.addUserListener("unique-tag", new CometChatUserEvents() {
@Override
public void ccUserBlocked(User user) { }
@Override
public void ccUserUnblocked(User user) { }
});CometChatGroupEvents
CometChatGroupEvents.addGroupListener("unique-tag", new CometChatGroupEvents() {
@Override
public void ccGroupCreated(Group group) { }
@Override
public void ccGroupDeleted(Group group) { }
@Override
public void ccGroupMemberJoined(User joinedUser, Group joinedGroup) { }
@Override
public void ccGroupMemberKicked(Action action, User kicked, User kickedBy, Group from) { }
@Override
public void ccGroupMemberBanned(Action action, User banned, User bannedBy, Group from) { }
});CometChatCallEvents
CometChatCallEvents.addListener("unique-tag", new CometChatCallEvents() {
@Override
public void ccOutgoingCall(Call call) { }
@Override
public void ccCallAccepted(Call call) { }
@Override
public void ccCallRejected(Call call) { }
@Override
public void ccCallEnded(Call call) { }
});---
5. Custom view slots on components
Most components support custom view injection via Function3<Context, User, Group, View>:
CometChatMessageHeader header = findViewById(R.id.header);
header.setSubtitleView((context, user, group) -> {
TextView subtitle = new TextView(context);
if (user != null) {
subtitle.setText(user.getStatus().equals("online") ? "Active now" : "Offline");
}
return subtitle;
});---
Hard rules
- Always extend `DataSourceDecorator`, never implement `DataSource` directly. The decorator preserves existing behavior.
- Register `ChatConfigurator.enable()` AFTER `CometChatUIKit.init()` succeeds. The configurator resets on init.
- Always remove event listeners when the Activity/Fragment is destroyed. Use
onDestroy()oronDestroyView(). - Template view slots use `MessagesViewHolderListener`. Implement both
createView()andbindView().