Reputation: 192
i have some code here for a an application chat screen. This specific chat screen is used to chat with a bot. The bot is supposed to send a message after each message by the user. The list of messages to be sent by the bot is stored in messageStrings. I'm using a listview.builder to populate the UI with new messages added in the List messages.
I'm using setstate to add new messages, but the UI Isn't getting updated with the new messages. This is my code:
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import '../models/chats.dart';
class ReportPage extends StatefulWidget {
BuildContext context;
ReportPage(this.context);
@override
_ReportPageState createState() => _ReportPageState();
}
class _ReportPageState extends State<ReportPage> {
@override
Widget build(Object context) {
TextEditingController messageContoller = new TextEditingController();
//The first two messages by the bot are already added to the List
List<ChatMessage> messages = [
ChatMessage(messageContent: "Message 1", messageType: "receiver"),
ChatMessage(messageContent: "Message 2", messageType: "receiver"),
];
int messageIndex = 0;
//The next messages that are to be added to the list after a response from the user
List<String> messageStrings = ["Message 3", "Message 4","Message 5",];
return Scaffold(
appBar: AppBar(
title: Row(children: [
Container(
width: 35,
height: 35,
child: Image.asset(
'assets/images/police.png',
fit: BoxFit.cover,
),
decoration:
BoxDecoration(shape: BoxShape.circle, color: Colors.white),
),
SizedBox(
width: 10,
),
Text("CFB bot"),
]),
),
body: Container(
padding: EdgeInsets.all(20),
child: Stack(
children: <Widget>[
ListView.builder(
itemCount: messages.length,
shrinkWrap: true,
padding: EdgeInsets.only(top: 10, bottom: 10),
physics: NeverScrollableScrollPhysics(),
itemBuilder: (context, index) {
return Container(
padding:
EdgeInsets.only(left: 14, right: 14, top: 10, bottom: 10),
child: Align(
alignment: (messages[index].messageType == "receiver"
? Alignment.topLeft
: Alignment.topRight),
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20),
color: (messages[index].messageType == "receiver"
? Colors.grey.shade200
: Colors.blue[200]),
),
padding: EdgeInsets.all(16),
child: Text(
messages[index].messageContent,
style: TextStyle(fontSize: 15),
),
),
),
);
},
),
Align(
alignment: Alignment.bottomLeft,
child: Container(
decoration: BoxDecoration(
border: Border.all(color: Colors.black),
borderRadius: BorderRadius.all(Radius.circular(20))),
padding: EdgeInsets.only(left: 10, bottom: 10, top: 10),
height: 60,
width: double.infinity,
child: Row(
children: <Widget>[
GestureDetector(
onTap: () {},
child: Container(
height: 30,
width: 30,
decoration: BoxDecoration(
color: Colors.lightBlue,
borderRadius: BorderRadius.circular(30),
),
child: Icon(
Icons.add,
color: Colors.white,
size: 20,
),
),
),
SizedBox(
width: 15,
),
Expanded(
child: TextField(
decoration: InputDecoration(
hintText: "Write message...",
hintStyle: TextStyle(color: Colors.black54),
border: InputBorder.none),
controller: messageContoller,
),
),
SizedBox(
width: 15,
),
FloatingActionButton(
onPressed: () {
String message = messageContoller.text;
setState(() {
messages.add(ChatMessage(messageContent: message, messageType: "sender"));
messages.add(ChatMessage(messageContent: messageStrings[messageIndex], messageType: "receiver"));
});
messageIndex++;
for(int i = 0; i < messages.length; i++){
print(messages[i].messageContent);
}
},
child: Icon(
Icons.send,
color: Colors.white,
size: 18,
),
backgroundColor: Colors.blue,
elevation: 0,
),
],
),
),
),
],
),
),
);
}
}
Upvotes: 1
Views: 1484
Reputation: 6405
Instead of directly using List.add
try changing the reference of your messages
to a completely new List
as well, like this,
messages = [
...messages,
ChatMessage(messageContent: message, messageType: "sender"),
ChatMessage(messageContent: messageStrings[messageIndex], messageType: "receiver")
];
Why this works is that now, you are destroying the old reference of the messages
and assigning it a completely new reference of List
.
Upvotes: 1