maphe
maphe

Reputation: 1931

ListView does not refresh whereas attached list does (Flutter)

I'm trying to get familiar with flutter and I'm facing some weird case. I want to build a dynamic ListView where a + button allows to add elements. I wrote the following State code:

class MyWidgetListState extends State<MyWidgetList> {
  List<Widget> _objectList = <Widget>[
    new Text('test'),
    new Text('test')
  ];

  void _addOne() {
    setState(() {
      _objectList.add(new Text('test'));
    });
  }

  void _removeOne() {
    setState(() {
      _objectList.removeLast();
    });
  }

  @override
  Widget build(BuildContext context) {
    return new Column(
      children: <Widget>[
        new ListView(
          shrinkWrap: true,
          children: _objectList
        ),
        new Row(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            new IconButton(
              icon: new Icon(Icons.remove_circle),
              iconSize: 36.0,
              tooltip: 'Remove',
              onPressed: _objectList.length > 2 ? _removeOne : null,
            ),
            new IconButton(
              icon: new Icon(Icons.add_circle),
              iconSize: 36.0,
              tooltip: 'Add',
              onPressed: _addOne,
            )
          ],
        ),
        new Text(_objectList.length.toString())
      ],
    );
  }
}

My problem here is that the ListView is visually stuck with the 2 elements I initialized it with.

Internally the _objectList is well managed. For testing purpose I added a simple Text widget at the bottom that shows the size of the list. This one works fine when I click the Add/Remove buttons and it gets properly refreshed. Am I missing something?

Upvotes: 10

Views: 11184

Answers (2)

Jitesh Mohite
Jitesh Mohite

Reputation: 34270

Another Solution!!

Replace ListView with ListView.builder

Code:

    ListView.builder(
            itemBuilder: (ctx, item) {
              return _objectList[item];
            },
            shrinkWrap: true,
            itemCount: _objectList.length,
          ),

Output:

enter image description here

Upvotes: 3

R&#233;mi Rousselet
R&#233;mi Rousselet

Reputation: 277667

Flutter is based around immutable data. Meaning that if the reference to an object didn't change, the content didn't either.

The problem is, in your case you always send to ListView the same array, and instead mutate its content. But this leads to ListView assuming the list didn't change and therefore prevent useless render.

You can change your setState to keep that in mind :

setState(() {
  _objectList = List.from(_objectList)
    ..add(Text("foo"));
});

Upvotes: 21

Related Questions