Skip to main content
This guide walks you through creating a tab-based messaging UI using Flutter and CometChat V6 UIKit. The UI includes sections for Chats, Users, and Groups, allowing seamless navigation.

User Interface Preview

This layout consists of:
  1. Sidebar (Conversation List) — Displays recent conversations with active users and groups.
  2. Message View — Shows the selected chat with real-time messages.
  3. Message Input Box — Allows users to send messages seamlessly.

Step 1: Render the Tab Component

Set up initialization and the tab-based layout. In V6, all list widgets (CometChatConversations, CometChatUsers, CometChatGroups) are powered by BLoC.

Full Example: main.dart

import 'package:flutter/material.dart';
import 'package:cometchat_chat_uikit/cometchat_chat_uikit.dart';
import 'messages_screen.dart';
import 'cometchat_config.dart';

void main() => runApp(const MyApp());

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'CometChat V6 UI Kit',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
      home: const Home(),
    );
  }
}

class Home extends StatelessWidget {
  const Home({super.key});

  Future<void> _initializeAndLogin() async {
    final settings = UIKitSettingsBuilder()
      ..subscriptionType = CometChatSubscriptionType.allUsers
      ..autoEstablishSocketConnection = true
      ..appId = CometChatConfig.appId
      ..region = CometChatConfig.region
      ..authKey = CometChatConfig.authKey;

    await CometChatUIKit.init(uiKitSettings: settings.build());
    await CometChatUIKit.login(
      'cometchat-uid-1',
      onSuccess: (_) => debugPrint('Login Successful'),
      onError: (err) => throw Exception('Login Failed: $err'),
    );
  }

  @override
  Widget build(BuildContext context) {
    return FutureBuilder<void>(
      future: _initializeAndLogin(),
      builder: (ctx, snap) {
        if (snap.connectionState != ConnectionState.done) {
          return const Scaffold(
            body: SafeArea(child: Center(child: CircularProgressIndicator())),
          );
        }
        if (snap.hasError) {
          return Scaffold(
            body: SafeArea(
              child: Center(child: Text('Error:\n${snap.error}', textAlign: TextAlign.center)),
            ),
          );
        }
        return const TabsScreen();
      },
    );
  }
}

class TabsScreen extends StatefulWidget {
  const TabsScreen({super.key});

  @override
  State<TabsScreen> createState() => _TabsScreenState();
}

class _TabsScreenState extends State<TabsScreen> {
  int _selectedIndex = 0;
  final PageController _pageController = PageController();

  void _onItemTapped(int index) {
    setState(() {
      _selectedIndex = index;
    });
    _pageController.jumpToPage(index);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: PageView(
        controller: _pageController,
        onPageChanged: (index) {
          setState(() {
            _selectedIndex = index;
          });
        },
        children: [
          CometChatConversations(
            showBackButton: false,
            onItemTap: (conversation) {
              Navigator.push(
                context,
                MaterialPageRoute(
                  builder: (context) => MessagesScreen(
                    user: conversation.conversationWith is User
                        ? conversation.conversationWith as User
                        : null,
                    group: conversation.conversationWith is Group
                        ? conversation.conversationWith as Group
                        : null,
                  ),
                ),
              );
            },
          ),
          CometChatUsers(),
          CometChatGroups(),
        ],
      ),
      bottomNavigationBar: BottomNavigationBar(
        currentIndex: _selectedIndex,
        onTap: _onItemTapped,
        items: const [
          BottomNavigationBarItem(icon: Icon(Icons.chat), label: "Chat"),
          BottomNavigationBarItem(icon: Icon(Icons.person), label: "Users"),
          BottomNavigationBarItem(icon: Icon(Icons.group), label: "Groups"),
        ],
      ),
    );
  }
}

Step 2: Render the Messages Component

Use the same MessagesScreen pattern from One-to-One Chat:
import 'package:flutter/material.dart';
import 'package:cometchat_chat_uikit/cometchat_chat_uikit.dart';

class MessagesScreen extends StatelessWidget {
  final User? user;
  final Group? group;

  const MessagesScreen({super.key, this.user, this.group});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: CometChatMessageHeader(user: user, group: group),
      body: SafeArea(
        child: Column(
          children: [
            Expanded(child: CometChatMessageList(user: user, group: group)),
            CometChatMessageComposer(user: user, group: group),
          ],
        ),
      ),
    );
  }
}

Step 3: Run the App

flutter run
This launches the app with the tab-based chat experience. Navigate between Chats, Users, and Groups tabs and interact with the messaging features.

Next Steps