SetState not working with listview.builder
535
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
.
Author by
Archangel
Updated on December 30, 2022Comments
-
Archangel over 1 year
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, ), ], ), ), ), ], ), ), ); } }
-
Archangel almost 3 yearsThanks for the answer. I tried this and it's still not updating the UI. is there any other way i can overcome this issue?
-
Nisanth Reddy almost 3 yearsThat is just not possible.
-
Nisanth Reddy almost 3 yearsSo you are saying, even if you change anything inside your setState, your UI is not rebuilding ?
-
Nisanth Reddy almost 3 yearsput a
print
statement inside your build function to check if it is getting called or not. -
Archangel almost 3 yearsSorry mate, the issue was that i put the List inside the build function. So, it was getting reset each time. I put it in the State Class and it's working fine now. Thanks for the help
-
Nisanth Reddy almost 3 yearsglad to have helped :)