I am trying to create a comment page. The list of comments are listed using ListView.builder. And when the user enter a comment, it will rebuild the list again to include the newly added comment. But somehow the list is not rebuild and i'm getting this message in terminal:

Changing the content within the the composing region may cause the input method to behave strangely, and is therefore discouraged. See https://github.com/flut ter/flutter/issues/78827 for more details

The newly added comment only shows when i close the comment page and reopen it again. Please help me, as i am not sure what is the issue and how to fix it.

Comment Page:

import 'package:flutter/material.dart';

import '../model/model_comment.dart';

class CommentsPage extends StatefulWidget {
  @override
  _CommentsPageState createState() => _CommentsPageState();
}

class _CommentsPageState extends State<CommentsPage> {
  ValueNotifier<int> _counter = ValueNotifier<int>(0);
  TextEditingController _controllerComment = TextEditingController();
  bool _hasComment = false;

  @override
  void dispose() {
    _controllerComment.dispose();
    super.dispose();
  }

  _commentOnSend() {
    setState(() {
      var value = CommentModel(
        avatarUrl: "https://randomuser.me/api/portraits/women/34.jpg",
        name: "Laurent Oslo",
        dateTime: "30 Dec 20 08:00",
        comment: _controllerComment.text,
      );
      CommentModel.dummyData.insert(0, value);
    });
    _controllerComment.clear();
    FocusScope.of(context).unfocus();
  }

  Widget _listView = ListView.builder(
    itemCount: CommentModel.dummyData.length,
    itemBuilder: (context, index) {
      CommentModel _model = CommentModel.dummyData[index];
      return Column(
        children: <Widget>[
          Divider(
            height: 12.0,
          ),
          Container(
            padding: EdgeInsets.fromLTRB(3.0, 3.0, 3.0, 3.0),
            child: ListTile(
              leading: CircleAvatar(
                radius: 24.0,
                backgroundImage: NetworkImage(_model.avatarUrl),
              ),
              title: Text(_model.name),
              subtitle: Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: [
                  Text(_model.comment),
                  Text(_model.dateTime),
                ],
              ),
            ),
          ),
        ],
      );
    },
  );

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("Comments"),
        titleSpacing: 40.0,
      ),
      body: Container(
        child: Column(
          children: [
            Expanded(child: _listView),
            Divider(
              height: 1.0,
            ),
            ListTile(
              leading: Container(
                height: 40.0,
                width: 40.0,
                decoration: BoxDecoration(
                    color: Colors.deepPurple,
                    borderRadius: BorderRadius.all(Radius.circular(50.0))),
                child: CircleAvatar(
                    radius: 50.0,
                    backgroundImage: NetworkImage(
                        "https://randomuser.me/api/portraits/men/83.jpg")),
              ),
              title: TextField(
                  decoration: (InputDecoration(
                    hintText: "Add Comment"
                  )),
                  minLines: 1,
                  maxLines: 5,
                  controller: _controllerComment,
                  onChanged: (val) {
                    setState(() {
                      _counter.value += 1;
                      if (val.isNotEmpty) {
                        _hasComment = true;
                      } else {
                        _hasComment = false;
                      }
                    });
                  }),
              trailing: ValueListenableBuilder(
                valueListenable: _counter,
                builder: (BuildContext context, int value, Widget? child) {
                  return IconButton(
                    onPressed: _hasComment
                        ? () {
                            _commentOnSend();
                          }
                        : null,
                    icon: Icon(Icons.send_sharp,
                        color: _hasComment ? Colors.deepPurple : null),
                  );
                },
              ),
            ),
          ],
        ),
      ),
    );
  }
}

Comment Model Class:

class CommentModel {
  final String avatarUrl;
  final String name;
  final String dateTime;
  final String comment;

  CommentModel(
      {required this.avatarUrl,
      required this.name,
      required this.dateTime,
      required this.comment});

  static List<CommentModel> dummyData = [
    CommentModel(
      avatarUrl: "https://randomuser.me/api/portraits/women/34.jpg",
      name: "Laurent Oslo",
      dateTime: "30 Dec 20 08:00",
      comment:
          "There is a reason why I implemented it like this. In a comment section, the same comment widget can appear multiple times. So, the keys assigned to each widget needs to be different. Otherwise I won’t be able to refer to a specific widget later on",
    ),
    CommentModel(
      avatarUrl: "https://randomuser.me/api/portraits/women/49.jpg",
      name: "Tracy Wilbur",
      dateTime: "01 Oct 20 17:00",
      comment: "First Comment!",
    ),
    CommentModel(
      avatarUrl: "https://randomuser.me/api/portraits/women/23.jpg",
      name: "Michael Scott",
      dateTime: "30 Sept 20 06:00",
      comment:
          "The idea is simple. Use the prefix with something else to make the key unique. In this case, I’ve used the index value to make them unique. I used the keys in line 25, 51, 56, and 60. See how I’ve done it in these lines.",
    ),
    CommentModel(
      avatarUrl: "https://randomuser.me/api/portraits/men/45.jpg",
      name: "Williams John",
      dateTime: "17 Sept 20 02:00",
      comment: "Join!",
    ),
    CommentModel(
      avatarUrl: "https://randomuser.me/api/portraits/women/77.jpg",
      name: "Claire Rach",
      dateTime: "15 Aug 20 19:00",
      comment:
          "I want the comment section to be hidden away. A user can view comments by tapping to expand a widget. Meaning, the comment section should be collapsible. It will toggle between expanded and collapsed mode when being tapped.",
    ),
    CommentModel(
      avatarUrl: "https://randomuser.me/api/portraits/men/81.jpg",
      name: "Joe Panama",
      dateTime: "05 Jul 20 03:00",
      comment:
          "A comment will have 3 data values which are commenting user details, time of comment posting and the actual text of the comment. I’ve created a “CommentModel” class to create this model.",
    ),
    CommentModel(
      avatarUrl: "https://randomuser.me/api/portraits/men/83.jpg",
      name: "Mark Hamill",
      dateTime: "09 Jun 20 15:00",
      comment:
          "Because comments are part of a post, “PostModel” needs to have a list of comment data. So I’ve modified “PostModel” to have a list of “CommentModel” objects. Refer to the code changes to see what I’ve done.",
    ),
    CommentModel(
      avatarUrl: "https://randomuser.me/api/portraits/men/85.jpg",
      name: "Williams Dafoe",
      dateTime: "25 May 20 20:00",
      comment:
          "Notice lines 18 to 29. I’ve used the “ExpansionTile” widget to create a collapsible list of comments. Each comment is a “_SingleComment” widget implemented in lines 34 to 67.",
    ),
    CommentModel(
      avatarUrl: "https://randomuser.me/api/portraits/men/98.jpg",
      name: "Phillips Mach",
      dateTime: "01 Apr 20 17:00",
      comment:
          "New to app development and flutter in general(high schooler). Can I use this template? Do I have to give credit or can I just use it? At the very least, can I see the source code so I can learn from it?",
    ),
    CommentModel(
      avatarUrl: "https://randomuser.me/api/portraits/men/12.jpg",
      name: "Joe Snowden",
      dateTime: "04 Mar 20 16:00",
      comment: "PM ME!",
    ),
  ];
}


Solution 1: user15873802

This is because you are putting your Listview.builder in a state variable which is expected behavior since state variables do not get reinitialized in rebuilds.

If you want to refactor you can create a new function to return it:

ListView getList(){
  return ListView.builder(
    itemCount: CommentModel.dummyData.length,
    itemBuilder: (context, index) {
      CommentModel _model = CommentModel.dummyData[index];
      return Column(
        children: <Widget>[
          Divider(
            height: 12.0,
          ),
          Container(
            padding: EdgeInsets.fromLTRB(3.0, 3.0, 3.0, 3.0),
            child: ListTile(
              leading: CircleAvatar(
                radius: 24.0,
                backgroundImage: NetworkImage(_model.avatarUrl),
              ),
              title: Text(_model.name),
              subtitle: Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: [
                  Text(_model.comment),
                  Text(_model.dateTime),
                ],
              ),
            ),
          ),
        ],
      );
    },
  );
}