Skip to main content
FieldValue
Packagecom.cometchat:chat-uikit-android
ComponentsCometChatConversations, CometChatCallLogs, CometChatUsers, CometChatGroups, CometChatMessageHeader, CometChatMessageList, CometChatMessageComposer
LayoutTabbed bottom navigation (Chats, Calls, Users, Groups) + fragment container
PrerequisiteComplete Integration Steps 1–4 first
PatternFull-featured messaging app with multiple sections
This guide builds a tabbed messaging UI — Chats, Calls, Users, and Groups tabs via BottomNavigationView, with each tab loading its CometChat component in a fragment container. This assumes you’ve already completed Integration (project created, dependencies installed, init + login working, theme set up).

What You’re Building

Three sections working together:
  1. Bottom navigation bar — switches between Chats, Calls, Users, and Groups
  2. Fragment container — renders the CometChat component for the active tab
  3. Dynamic content — each tab loads its respective Fragment with real-time data
This uses Android’s BottomNavigationView pattern: TabbedActivity hosts the navigation and fragment container, user taps a tab, the corresponding Fragment loads.

Step 1: Set Up Tabbed Activity

Create a new Activity called TabbedActivity with BottomNavigationView to manage tab navigation.

Project Structure

Create the following files in your Android project:
src/main/java/your-package-name/
├── TabbedActivity.kt (or .java)
├── ChatsFragment.kt (or .java)
├── CallLogsFragment.kt (or .java)
├── UsersFragment.kt (or .java)
└── GroupsFragment.kt (or .java)

src/main/java/your-package-name/
├── res/
│   ├── layout/
│   │   ├── activity_tabbed.xml
│   │   ├── fragment_chats.xml
│   │   ├── fragment_call_logs.xml
│   │   ├── fragment_users.xml
│   │   └── fragment_groups.xml
│   └── menu/
│       └── bottom_nav_menu.xml

Vector Drawable Icons

Download the navigation icons from the CometChat UI Kit repository: 🔗 GitHub Drawable Resources Place the icon files (ic_chats.xml, ic_calls.xml, ic_user.xml, ic_group.xml) in your res/drawable/ directory.

Implementation

TabbedActivity.kt
import android.os.Bundle
import androidx.activity.enableEdgeToEdge
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
import androidx.fragment.app.Fragment

import com.google.android.material.bottomnavigation.BottomNavigationView

class TabbedActivity : AppCompatActivity() {

    private lateinit var bottomNavigationView: BottomNavigationView

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        enableEdgeToEdge()
        setContentView(R.layout.activity_tabbed)

        setupWindowInsets()
        initViews()
        setupNavigation(savedInstanceState)
    }

    private fun setupWindowInsets() {
        ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main)) { v, insets ->
            val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars())
            v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom)
            insets
        }
    }

    private fun initViews() {
        bottomNavigationView = findViewById(R.id.bottomNavigationView)
    }

    private fun setupNavigation(savedInstanceState: Bundle?) {
        bottomNavigationView.setOnItemSelectedListener { item ->
            val fragment = createFragmentForNavItem(item.itemId)
            replaceFragment(fragment)
            true
        }

        // Set default fragment only when activity is first created
        if (savedInstanceState == null) {
            replaceFragment(ChatsFragment())
            bottomNavigationView.selectedItemId = R.id.nav_chats
        }
    }

    private fun createFragmentForNavItem(itemId: Int): Fragment {
        return when (itemId) {
            R.id.nav_chats -> ChatsFragment()
            R.id.nav_call_logs -> CallLogsFragment()
            R.id.nav_users -> UsersFragment()
            R.id.nav_groups -> GroupsFragment()
            else -> ChatsFragment()
        }
    }

    private fun replaceFragment(fragment: Fragment) {
        supportFragmentManager.beginTransaction()
            .replace(R.id.fragmentContainer, fragment)
            .commit()
    }
}
You must use an activity that supports the lifecycle API, such as:
  • AppCompatActivity
  • ComponentActivity
  • FragmentActivity
This is necessary to properly manage the UI Kit’s lifecycle events.

Step 2: Create Fragments for Each Tab

Each tab displays a different CometChat UI component wrapped in a Fragment.

Chats Fragment

ChatsFragment.kt
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup

import androidx.fragment.app.Fragment

class ChatsFragment : Fragment() {

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
    ): View? {
        return inflater.inflate(R.layout.fragment_chats, container, false)
    }
}

Call Logs Fragment

Make sure you’ve added the Calls SDK dependency to enable voice and video calling features.
CallLogsFragment.kt
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup

import androidx.fragment.app.Fragment

class CallLogsFragment : Fragment() {

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
    ): View? {
        return inflater.inflate(R.layout.fragment_call_logs, container, false)
    }
}

Users Fragment

UsersFragment.kt
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup

import androidx.fragment.app.Fragment

class UsersFragment : Fragment() {

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
    ): View? {
        return inflater.inflate(R.layout.fragment_users, container, false)
    }
}

Groups Fragment

GroupsFragment.kt
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup

import androidx.fragment.app.Fragment

class GroupsFragment : Fragment() {

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
    ): View? {
        return inflater.inflate(R.layout.fragment_groups, container, false)
    }
}

Step 3: Launch TabbedActivity from Your App

Update your MainActivity to launch TabbedActivity after successful login:
MainActivity.kt
import android.content.Intent
import android.os.Bundle
import android.util.Log
import androidx.activity.ComponentActivity
import androidx.activity.enableEdgeToEdge
import com.cometchat.chat.core.CometChat
import com.cometchat.chat.exceptions.CometChatException
import com.cometchat.chat.models.User
import com.cometchat.chatuikit.shared.cometchatuikit.CometChatUIKit
import com.cometchat.chatuikit.shared.cometchatuikit.UIKitSettings

class MainActivity : ComponentActivity() {

    private val TAG = "MainActivity"

    private val appID = "APP_ID" // Replace with your App ID
    private val region = "REGION" // Replace with your App Region
    private val authKey = "AUTH_KEY" // Replace with your Auth Key or leave blank if you are authenticating using Auth Token

    private val uid = "cometchat-uid-1" // Replace with the UID of the user you want to log in

    private val uiKitSettings = UIKitSettings.UIKitSettingsBuilder()
        .setRegion(region)
        .setAppId(appID)
        .setAuthKey(authKey)
        .subscribePresenceForAllUsers()
        .build()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        enableEdgeToEdge()

        CometChatUIKit.init(this, uiKitSettings, object : CometChat.CallbackListener<String?>() {
            override fun onSuccess(successString: String?) {

                Log.d(TAG, "Initialization completed successfully")

                loginUser()
            }

            override fun onError(e: CometChatException?) {}
        })
    }

    private fun loginUser() {
        CometChatUIKit.login(uid, object : CometChat.CallbackListener<User>() {
            override fun onSuccess(user: User) {
 
                // Launch Tab-Based Chat Experience (Chats, Calls, Users, Groups)
                startActivity(Intent(this@MainActivity, TabbedActivity::class.java))
            }

            override fun onError(e: CometChatException) {
                // Handle login failure (e.g. show error message or retry)
                Log.e("Login", "Login failed: ${e.message}")
            }
        })
    }
}

Running the Application

Once you’ve completed the setup, build and run your Android application:
gradle build
Required PermissionsEnsure you’ve added the necessary permissions in your AndroidManifest.xmland initialized CometChat in your Application class:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
For Call Features, also add:
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />

Next Steps