]

Flutter Chat UI Tutorial

Last updated Mar 30, 2020

Flutter Chat UI Pages

In this post, we will create the layout of a Chat UI.

Step 1: Create Flutter Application

Step 2: Add required resourses 

Step 3: Create Model classes

User Model

 
class User{
  final int id;
  final String name;
  final String imageUrl;

  User({this.id,this.name,this.imageUrl});
}

 

Message Model

 
import 'package:flutter_chat_ui/models/user_model.dart';

class Message{
  final User sender;
  final String time;
  final String text;
  final bool isLiked;
  final bool unread;

  Message({this.sender,this.time,this.text,this.isLiked,this.unread});
}

//You Current User
final User currentUser=User(
  id:0,
  name: 'Current User',
  imageUrl: 'assets/images/user0.png'
);

final User user1=User(id:1,name:'Blck Window',imageUrl: 'assets/black.jpg');

final User user2=User(id:2,name:'Hulk',imageUrl: 'assets/hulk.jpg');
final User user3=User(id:3,name:'Captain America',imageUrl: 'assets/captain.jpg');
final User user4=User(id:4,name:'Iron Man',imageUrl: 'assets/ironman.jpg');
final User user5=User(id:5,name:'Thor',imageUrl: 'assets/thor.jpg');

Listfavorite=[user1,user2,user3,user4,user5];

Listchats=[
  Message(sender:user1,time:'5:30 PM',text: 'Hey, how\'s it going? What did you do today?',isLiked:false,unread:true),
  Message(sender:user2,time:'3:30 PM',text: 'Hey, how\'s it going? What did you do today?',isLiked:false,unread:false),
  Message(sender:user3,time:'1:30 PM',text: 'Hey, how\'s it going? What did you do today?',isLiked:true,unread:true),
  Message(sender:user1,time:'2:30 AM',text: 'Hey, how\'s it going? What did you do today?',isLiked:false,unread:true),
  Message(sender:user1,time:'2:00 PM',text: 'Hey, how\'s it going? What did you do today?',isLiked:false,unread:true),
];

//Example Messages
Listmessages=[
  Message(sender:user1,time:'5:30 PM',text: 'Hey, how\'s it going? What did you do today?',isLiked:true,unread:true),
  Message(sender:currentUser,time:'4:30 PM',text: 'Just walked my doge. She was super duper',isLiked:false,unread:true),
  Message(sender:user1,time:'1:30 PM',text: 'How is the doggo?',isLiked:true,unread:true),
  Message(sender:currentUser,time:'2:30 AM',text: 'All the food',isLiked:false,unread:true),
  Message(sender:user1,time:'2:30 PM',text:'Nice, What kind of food you eat?',isLiked:false,unread:true),
  Message(sender:currentUser,time:'2:00 AM',text:'I ate so much of food today',isLiked:false,unread:true),
];

 

Step 4: Create HomScreen

This HomeScreen contains 3 sections

  • Category Section
  • Favorite Contacts
  • RecentChats

Category Section

 
import 'package:flutter/material.dart';

class CategorySelector extends StatefulWidget{
  @override
  State createState() {
    // TODO: implement createState
    return _CategorySelectorState();
  }

}

class _CategorySelectorState extends State{
  int selectedIndex=0;
  Listcategories=['Messages','Online','Groups','Requests'];
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Container(
    height:70.0,
      color: Theme.of(context).primaryColor,
      child: ListView.builder(
        scrollDirection: Axis.horizontal,
        itemCount: categories.length,
          itemBuilder: (BuildContext context,int index){

          return GestureDetector(
            onTap: (){
              setState((){
                selectedIndex=index;
              });
            },
            child: Padding(
              padding: EdgeInsets.symmetric(horizontal: 10,vertical: 20),
              child: Text(categories[index],style: TextStyle(
                color: (index==selectedIndex)?Colors.white:Colors.white60,
                fontWeight: FontWeight.bold,
                fontSize: 18.0,
                letterSpacing: 1.2,
              ),),
            ),
          );
      }),
    );
  }

}

 

Favorite Contact

 
import 'package:flutter/material.dart';
import 'package:flutter_chat_ui/models/message_model.dart';
import 'package:flutter_chat_ui/screens/chatscreen.dart';

class FavoriteContacts extends StatelessWidget{
  @override
  Widget build(BuildContext context) {
    // TODO: implement build

    return Padding(
      padding:  EdgeInsets.symmetric(vertical: 10,horizontal: 16),
      child: Column(
        children: [
          Padding(
            padding:  EdgeInsets.symmetric(horizontal: 20),
            child: Row(
              mainAxisAlignment: MainAxisAlignment.spaceBetween,
              children: [
                Text("Favourite Contacts",style: TextStyle(color: Colors.blueGrey,fontSize: 16.0,fontWeight: FontWeight.bold),),
                IconButton(icon: Icon(Icons.more_horiz),color: Colors.blueGrey, onPressed: (){

                })
              ],
            ),
          ),
          Container(
            height: 100,
            child: ListView.builder(
              scrollDirection: Axis.horizontal,
                itemCount: favorite.length,
                itemBuilder: (BuildContext context,int index){
              return GestureDetector(
                onTap: (){Navigator.push(context, MaterialPageRoute(builder: (_){
                  return ChatScreen(user:favorite[index]);
                }));
                },
                child: Padding(padding: EdgeInsets.all(8),
                  child:
                  Column(
                    children: [
                      CircleAvatar(
                        radius: 30,
                          backgroundImage: AssetImage(favorite[index].imageUrl),
                      ),
                      SizedBox(height: 6.0,),
                      Text(favorite[index].name,style: TextStyle(color:Colors.blueGrey,fontWeight: FontWeight.bold,fontSize: 14.0),)
                    ],
                  ),),
              );
            }),
          )
        ],
      ),
    );
  }

}

 

Recent Chats

 
import 'package:flutter/material.dart';
import 'package:flutter_chat_ui/models/message_model.dart';
import 'package:flutter_chat_ui/screens/chatscreen.dart';

class RecentChats extends StatefulWidget{
  @override
  State createState() {
    // TODO: implement createState
    return _RecentChatsState();
  }

}

class _RecentChatsState extends State{
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Expanded(
      child: Container(
        decoration: BoxDecoration(
          borderRadius: BorderRadius.only(topRight: Radius.circular(30),topLeft: Radius.circular(30))
        ),
        child: ClipRRect(
            borderRadius: BorderRadius.only(topRight: Radius.circular(30),topLeft: Radius.circular(30)),
          child: ListView.builder(
              itemCount: chats.length,

              itemBuilder: (context,index){
            Message chat=chats[index];
            return GestureDetector(
              onTap: (){Navigator.push(context, MaterialPageRoute(builder: (_){
                return ChatScreen(user:chat.sender);
              }));
              },
              child: Container(
                margin: EdgeInsets.only(top: 5.0,right: 20.0,bottom: 5.0),
                padding: EdgeInsets.symmetric(vertical: 10,horizontal: 20),
                decoration: BoxDecoration(
                  borderRadius: BorderRadius.only(topRight: Radius.circular(20),bottomRight: Radius.circular(20)),
                  color: chat.unread?Color(0XFFFFEFEE):Colors.white
                ),
                child: Row(
                  mainAxisAlignment: MainAxisAlignment.spaceBetween,
                  children: [
                    Row(
                      children: [
                        CircleAvatar(radius: 30,backgroundImage: AssetImage(chat.sender.imageUrl),),
                        SizedBox(width: 10,),
                        Column(
                          crossAxisAlignment: CrossAxisAlignment.start,
                          children: [
                            Text(chat.sender.name,style: TextStyle(fontSize: 14.0,fontWeight: FontWeight.bold,color: Colors.grey),),
                            SizedBox(height: 10,),
                            Container(width:MediaQuery.of(context).size.width*.45,
                                child: Text(chat.text,
                                  style: TextStyle(fontSize: 12.0,fontWeight: FontWeight.w600,color: Colors.blueGrey),
                                overflow: TextOverflow.ellipsis,
                                )),
                          ],
                        )
                      ],
                    ),
                    Column(
                      children: [
                        Text(chat.time,style: TextStyle(color: Colors.grey,fontWeight: FontWeight.bold,fontSize: 15.0),),
                        SizedBox(height: 5.0,),
                        chat.unread?Container(width:40,height:20,alignment:Alignment.center,decoration:BoxDecoration(color: Theme.of(context).primaryColor,borderRadius: BorderRadius.all(Radius.circular(30))),child: Text('New',style: TextStyle(color: Colors.white,fontSize: 12.0,fontWeight: FontWeight.bold),)):Text(''),
                      ],
                    )
                  ],
                ),
              ),
            );
          }),
        ),
      ),
    );
  }

}

 

HomeScreen

 
import 'package:flutter/material.dart';
import 'package:flutter_chat_ui/widgets/category_selector.dart';
import 'package:flutter_chat_ui/widgets/favorite_contacts.dart';
import 'package:flutter_chat_ui/widgets/recent_chats.dart';

class HomeScreen extends StatefulWidget{


  @override
  State createState() {
    // TODO: implement createState
    return _HomeScreenState();
  }

}
class _HomeScreenState extends State
{

  @override
  Widget build(BuildContext context) {
    // TODO: implement build
   return Scaffold(
     backgroundColor: Theme.of(context).primaryColor,
     appBar: AppBar(
       leading: IconButton(icon: Icon(Icons.menu,), iconSize: 30.0,color: Colors.white, onPressed: (){}),

       title: Text("Chats",style: TextStyle(fontSize: 28.0,fontWeight: FontWeight.bold),),
     elevation: 0.0,
       actions: [
         IconButton(icon: Icon(Icons.search,), iconSize: 30.0,color: Colors.white, onPressed: (){})
       ],
     ),

     body: Column(
       children: [
         CategorySelector(),
         Expanded(child: Container(
           decoration: BoxDecoration(
             color: Theme.of(context).accentColor,
             borderRadius: BorderRadius.only(topLeft: Radius.circular(30),topRight: Radius.circular(30))
           ),
           child: Column(
             children: [
               FavoriteContacts(),
               RecentChats(),
             ],
           ),
         ))
       ],
     ),
   );
  }

}

 

Step 5: Chat Screen

 
import 'package:flutter/material.dart';
import 'package:flutter_chat_ui/models/message_model.dart';
import 'package:flutter_chat_ui/models/user_model.dart';

class ChatScreen extends StatefulWidget{
  ChatScreen({this.user});
  User user;
  @override
  State createState() {
    // TODO: implement createState
    return _ChatScreenState();
  }

}
class _ChatScreenState extends State{
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Scaffold(
      backgroundColor: Theme.of(context).primaryColor,
appBar: AppBar(
  title: Text(widget.user.name,style: TextStyle(fontSize: 28.0,fontWeight: FontWeight.bold),),
  actions: [
    IconButton(icon: Icon(Icons.more_horiz,), iconSize: 30.0,color: Colors.white, onPressed: (){})
  ],
  elevation: 0.0,
),
      body: GestureDetector(
        onTap: (){FocusScope.of(context).unfocus();},
        child: Column(
          children: [
            Expanded(
              child: Container(
                decoration: BoxDecoration(color: Colors.white,borderRadius: BorderRadius.only(topRight: Radius.circular(30),topLeft: Radius.circular(30))),
             child: ClipRRect(
               borderRadius: BorderRadius.only(topRight: Radius.circular(30),topLeft: Radius.circular(30),),
               child: Padding(
                 padding: const EdgeInsets.only(top: 20),
                 child: ListView.builder(
                   reverse: true,
                     itemCount: messages.length,
                     itemBuilder: (contx,index){
                   Message message=messages[index];
                   bool isMe=message.sender.id==currentUser.id;
                   return _buildMessages(message,isMe);
                 }),
               ),
             ),
              ),
            ),
            _buildComposer(),
          ],
        ),
      ),
    );
  }


   _buildMessages(Message message,isMe) {
     msg()
     {
       return Container(
         width: MediaQuery.of(context).size.width*.75,
         decoration: BoxDecoration(
             color: isMe?Theme.of(context).accentColor:Color(0XFFFFEFEE),
             borderRadius: isMe? BorderRadius.only(topLeft: Radius.circular(15),bottomLeft: Radius.circular(15)): BorderRadius.only(topRight: Radius.circular(15),bottomRight: Radius.circular(15))
         ),
         margin: isMe?EdgeInsets.only(top: 8.0,bottom: 8.0,left: 80):EdgeInsets.only(top: 8.0,bottom: 8.0),
         padding:  const EdgeInsets.symmetric(horizontal: 25,vertical: 15),
         child: Column(
           crossAxisAlignment: CrossAxisAlignment.start,
           children: [
             Text(message.time,style: TextStyle(color: Colors.blueGrey,fontWeight: FontWeight.bold,fontSize: 10),),
             SizedBox(height: 10.0,),
             Text(message.text,style: TextStyle(color: Colors.grey,fontWeight: FontWeight.bold,fontSize: 12),),
           ],
         ),
       );
     }
     if(isMe)
       {
         return msg();
       }
    return Row(
      children: [
        msg(),
       message.isLiked? IconButton(icon: Icon(Icons.favorite),color:Theme.of(context).primaryColor, onPressed: (){}):IconButton(icon: Icon(Icons.favorite_border,color: Colors.blueGrey,), onPressed: (){})
      ],
    );
   }

  _buildComposer() {
    return Container(
      decoration: BoxDecoration(
        color: Colors.white,
       border: Border.all(color: Colors.grey,width: 1)
      ),

      height: 70,
      child: Row(
        children: [
          IconButton(icon: Icon(Icons.camera_alt,color:Theme.of(context).primaryColor,size: 35,), onPressed: null),
          Expanded(child: TextField(

            decoration: InputDecoration.collapsed(hintText: "Write your message"),
          ),),
          IconButton(icon: Icon(Icons.send,color:Theme.of(context).primaryColor,size: 35), onPressed: null),
        ],
      ),
    );
  }

}

 

Step 6: Update main.dart file

 
import 'package:flutter/material.dart';

import 'package:flutter_chat_ui/screens/homescreen.dart';

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

class MyApp extends StatelessWidget{
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
   return MaterialApp(
     debugShowCheckedModeBanner: false,
     title: "Chat Message UI",
     theme: ThemeData(
       primaryColor: Colors.red,
       accentColor: Color(0XFFF7F9F9)
     ),
     home: HomeScreen(),
   );
  }

}
 

Step 7: Run application

Flutter Chat UI

Flutter Chat UI

 

Download complete code 


Article Contributed By :
https://www.rrtutors.com/site_assets/profile/assets/img/avataaars.svg

541 Views

Subscribe For Daily Updates

Flutter Questions
Android Questions