Home > Mobile >  Flutter - ListView's items' row tile not updating on state build
Flutter - ListView's items' row tile not updating on state build

Time:08-10

The list doesn't update after an item removed. It only removes the last row. I simplified the code as much as possible since I can't see anything wrong elsewhere. Either this is weird or I was missing something.

class ListState extends State<ListWidget>{

  ...

  List<Item> list = [];

  @override
  Widget build(BuildContext context) {
    print([for(Item item in list) item.name]); //The list is updated so nothing wrong here
    List<Tile> children = [];
    for(Item item in list) children.add(Tile(item) .. parent = this);
    return ListView(children : children, controller : controller);
  }

  void remove(Item item) => setState((){
    list.remove(item);
  });

  ...
}

class Tile extends StatefulWidget{

  Item item;
  ListState parent;

  Tile(this.item);

  @override
  State<StatefulWidget> createState() => TileState() .. item = item;
}

class TileState extends State<Tile>{

  Item item;

  @override
  Widget build(BuildContext context) => ListTile(
      key: ValueKey(item.name),
      title: Text(item.name),
      onTap: () => widget.parent.remove(item),
    );
}

CodePudding user response:

The issue occurs from callback, you can direclty using VoidCallBack

Changes on Tile

class Tile extends StatefulWidget {
  final _HomeItem item;
  final Function delete;

  Tile(this.item, this.delete);

  @override
  State<StatefulWidget> createState() => _TileState();
}

class _TileState extends State<Tile> {
  @override
  Widget build(BuildContext context) {
    return ListTile(
      title: Text("${widget.item.title}"),
      subtitle: Text("${widget.item.index}"),
      onTap: () => widget.delete(),
    );
  }
}

And use case

return Tile(items[index], () {
  items.remove(items[index]);
  setState(() {});
});

Full Snippet


class MyHomePage extends StatefulWidget {
  final String title = "F";

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  final List<_HomeItem> items = List.generate(
    5,
    (i) => _HomeItem(
      i,
      'Tile n°$i',
    ),
  );

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: _buildList(context),
      ),
    );
  }

  Widget _buildList(BuildContext context) {
    return ListView.builder(
      itemBuilder: (context, index) {
        return Tile(items[index], () {
          items.remove(items[index]);
          setState(() {});
        });
      },
      itemCount: items.length,
    );
  }
}

class Tile extends StatefulWidget {
  final _HomeItem item;
  final Function delete;

  Tile(this.item, this.delete);

  @override
  State<StatefulWidget> createState() => _TileState();
}

class _TileState extends State<Tile> {
  @override
  Widget build(BuildContext context) {
    return ListTile(
      title: Text("${widget.item.title}"),
      subtitle: Text("${widget.item.index}"),
      onTap: () => widget.delete(),
    );
  }
}

class _HomeItem {
  const _HomeItem(
    this.index,
    this.title,
  );

  final int index;
  final String title;
}

CodePudding user response:

https://pub.dev/packages/lodash_flutter

List singleList = [1, 2, 3, 4];
    List list = [
      {'id': 1},
      {
        'id': 2,
      },
      {'id': 3}
    ];

    List singleChildren = [];

    for (var i in singleList) {
      singleChildren.add(i);
    }
    singleChildren.remove(1);
    print(singleChildren); //[2, 3]

    ///Multidimension array

    List multiChildren = [];
    for (var i in list) {
      multiChildren.add({'id': i['id']});
    }

    multiChildren.removeWhere((item) => item['id'] == 2);
    print(multiChildren);

    /// [{id: 2}, {id: 3}]
  • Related