Chat app screen UI.
Today we make a chat app UI in a flutter. flutter is already popular with its awesome UI elements.
there are already plugins named flutter_chat_ui to make chat full-screen UI but we do it without using the plugin. these days many people use chat applications for communicating with each other long distances. nowadays there is a high demand for an attractive and powerful user interface, which impacts the user experience.
Chat app screen UI
let's get started!
How to create a simple main home screen.
First, you remove the default code generated when the project is created. and create simple MaterialApp
Inside MaterialApp add Container as the home screen. create a button to go chat screen.
How to create chat message UI.
First, you need to add a plugin named flutter_chat_bubble package that makes it easy to create the design chat message.
installation:-
Add package into the pusbpec.yaml file:-
dependencies:
flutter_chat_bubbble:
Import package where you want to use:-
import 'package:flutter_chat_bubble/chat_bubble.dart';
Remaining functionality and data
Use this plugin's custom UI method and function and make a textInputField at the end of the screen. on adding a message by the user stored in a list in form of the map
Like this:-
At the end, when data was added to the list call the autoScroll function to auto-scroll to the maximum length of the list we added.
Auto Scroll function is guided in this blog:- Auto scroll is here
The full explanation code is here:-
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:chat_bubbles/chat_bubbles.dart';
import 'package:flutter_chat_bubble/bubble_type.dart';
import 'package:flutter_chat_bubble/chat_bubble.dart';
import 'package:flutter_chat_bubble/clippers/chat_bubble_clipper_1.dart';
class DemoBlogDart extends StatefulWidget {
const DemoBlogDart({Key? key}) : super(key: key);
@override
State<DemoBlogDart> createState() => _DemoBlogDartState();
}
class _DemoBlogDartState extends State<DemoBlogDart> {
var listAdd = [];
final TextEditingController _text = TextEditingController();
ScrollController? _scrollController;
@override
void initState() {
super.initState();
listAdd.add({
'isImage': false,
'otherUser': true,
'text': 'hello',
'time': '${DateTime.now()}',
});
listAdd.add({
'isImage': false,
'otherUser': false,
'text': 'hi',
'time': '${DateTime.now()}',
});
listAdd.add({
'isImage': false,
'otherUser': true,
'text': 'how are you',
'time': '${DateTime.now()}',
});
listAdd.add({
'isImage': false,
'otherUser': false,
'text': 'I\'m fine',
'time': '${DateTime.now()}',
});
_scrollController = ScrollController(initialScrollOffset: 0);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("Chat Demo"),
),
body: Container(
child: Stack(
fit: StackFit.loose,
children: <Widget>[
Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
DateChip(date: DateTime.now()),
const SizedBox(
height: 10,
),
Flexible(
fit: FlexFit.tight,
child: Container(
child: ListView.builder(
itemCount: listAdd.length,
controller: _scrollController,
itemBuilder: (context, index) {
return Container(
child: Padding(
padding: const EdgeInsets.only(
left: 30, right: 30),
child: listAdd[index]['otherUser'] == true
? Row(
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
Container(
height: 60,
alignment:
Alignment.topCenter,
child: Container(
height: 40,
width: 40,
decoration: const BoxDecoration(
shape: BoxShape.circle,
image: DecorationImage(
image: AssetImage(
"assets/female_icon.jpeg"),
fit: BoxFit.fill)),
)),
const SizedBox(
width: 2,
),
Container(
padding:
const EdgeInsets.only(
top: 25),
child: ChatBubble(
clipper: ChatBubbleClipper1(
type: BubbleType
.receiverBubble),
backGroundColor:
Colors.blue,
child: Column(
children: [
Container(
constraints:
BoxConstraints(
maxWidth: MediaQuery.of(
context)
.size
.width *
0.5,
),
child: Text(
'${listAdd[index]['text']}',
style:
const TextStyle(
color: Colors
.black),
),
),
],
),
)),
const Expanded(
child: SizedBox.shrink())
],
)
: Container(
child: Row(
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
const Expanded(
child: SizedBox.shrink()),
Container(
padding:
const EdgeInsets.only(
top: 25),
child: ChatBubble(
clipper:
ChatBubbleClipper1(
type: BubbleType
.sendBubble),
backGroundColor:
Colors.pink[200],
child: Column(
children: [
Container(
constraints:
BoxConstraints(
maxWidth: MediaQuery.of(
context)
.size
.width *
0.5,
),
child: Text(
'${listAdd[index]['text']}',
style: const TextStyle(
color: Colors
.black),
),
),
],
),
)),
Container(
height: 60,
alignment:
Alignment.topCenter,
child: Container(
height: 40,
width: 40,
decoration: const BoxDecoration(
shape:
BoxShape.circle,
image: DecorationImage(
image: AssetImage(
"assets/watch.png"),
fit: BoxFit
.fill))))
],
),
)));
})),
),
Container(
height: 50,
color: Colors.blue[400],
child: Padding(
padding: const EdgeInsets.only(left: 8.0),
child: TextField(
maxLines: 20,
style: const TextStyle(color: Colors.white),
controller: _text,
decoration: InputDecoration(
// focusColor: Color(0xFF050504),
prefixIcon: GestureDetector(
onTap: () async {
// await getImage();
listAdd.add({
'isImage': true,
'otherUser': false,
});
},
child: const Icon(
Icons.attachment,
color: Colors.white,
)),
suffixIcon: Row(
crossAxisAlignment: CrossAxisAlignment.end,
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.start,
children: [
IconButton(
icon: Icon(
Icons.send,
color: Colors.pink[200],
),
onPressed: () {
if (_text.text.isEmpty) {
return null;
} else {
// _sendMessage();
// channel.sink.add(_text.text);
setState(() {
listAdd.add({
'isImage': false,
'text': _text.text,
'time':
'${DateTime.now().hour}:${DateTime.now().minute}',
'otherUser': false,
});
});
setState(() {
_text.text = '';
});
}
},
),
],
),
hintStyle: TextStyle(color: Colors.white),
border: InputBorder.none,
hintText: "enter your message",
),
),
),
),
],
),
],
),
),
);
//
}
}