This guide builds a sequential navigation chat layout — conversation list as the entry point, tap a conversation to open a full-screen message view.This assumes you’ve already completed the integration guide for your chosen UI toolkit (project created, dependencies installed, init + login working).
Conversation list — shows all active conversations (users and groups)
Message header — displays user/group name, avatar, and status
Message list + composer — chat history with real-time updates and text input
Kotlin (XML Views)
Jetpack Compose
This implementation uses Android’s standard Activity navigation: ConversationActivity displays the list, user taps a conversation, MessageActivity launches with the selected user/group data via Intent extras.
This implementation uses Compose state to manage navigation between the conversation list and message screen — no Activities or Fragments needed beyond your MainActivity.
import android.content.Intentimport android.os.Bundleimport android.util.Logimport androidx.activity.enableEdgeToEdgeimport androidx.appcompat.app.AppCompatActivityimport com.cometchat.chat.models.Groupimport com.cometchat.chat.models.Userimport com.cometchat.uikit.kotlin.presentation.conversations.ui.CometChatConversationsclass ConversationActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) enableEdgeToEdge() setContentView(R.layout.activity_conversation) val conversations = findViewById<CometChatConversations>(R.id.conversations) conversations.setTitle("Chats") conversations.setOnItemClick { conversation -> val intent = Intent(this, MessageActivity::class.java) when (val entity = conversation.conversationWith) { is User -> intent.putExtra("user", entity) is Group -> intent.putExtra("group", entity) else -> Log.e("ConversationActivity", "Unknown conversation type") } startActivity(intent) } }}
You must use an activity that supports the lifecycle API (AppCompatActivity, ComponentActivity, or FragmentActivity) to properly manage the UI Kit’s lifecycle events.
Create a ChatApp.kt file with the root composable that manages navigation between the conversation list and message screen:
ChatApp.kt
import androidx.compose.runtime.Composableimport androidx.compose.runtime.getValueimport androidx.compose.runtime.mutableStateOfimport androidx.compose.runtime.rememberimport androidx.compose.runtime.setValueimport com.cometchat.chat.models.Groupimport com.cometchat.chat.models.User@Composablefun ChatApp() { var selectedUser by remember { mutableStateOf<User?>(null) } var selectedGroup by remember { mutableStateOf<Group?>(null) } val inChat = selectedUser != null || selectedGroup != null if (!inChat) { ConversationsScreen( onConversationClick = { user, group -> selectedUser = user selectedGroup = group } ) } else { MessageScreen( user = selectedUser, group = selectedGroup, onBack = { selectedUser = null selectedGroup = null } ) }}
Add the ConversationsScreen composable:
ChatApp.kt
import androidx.compose.foundation.layout.fillMaxSizeimport androidx.compose.ui.Modifierimport com.cometchat.uikit.compose.presentation.conversations.ui.CometChatConversations@Composablefun ConversationsScreen( onConversationClick: (User?, Group?) -> Unit) { CometChatConversations( modifier = Modifier.fillMaxSize(), title = "Chats", onItemClick = { conversation -> when (val entity = conversation.conversationWith) { is User -> onConversationClick(entity, null) is Group -> onConversationClick(null, entity) } } )}