Archangel
Archangel

Reputation: 192

SetState not working with listview.builder

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

Answers (1)

Nisanth Reddy
Nisanth Reddy

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

Related Questions