Search code examples
flutterflutter-listview

ListView update doesn't update after new ListTile gets added as a children in Flutter


I have a simple flutter app which just shows the ListTiles of a ListView... This listView's children property is set to a list called "tiles"... Whenever user presses the floating action button then then a new ListTiles object gets added to "tiles" and this is wrapped inside set state... so I would expect the UI to update and show me new updated listView with more ListTiles... but that doesn't happen...

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Home(),
    );
  }
}

class Home extends StatefulWidget {
  @override
  _HomeState createState() => _HomeState();
}

class _HomeState extends State<Home> {
  List<ListTile> tiles = [];

  @override
  Widget build(BuildContext context) {
    print('length of tiles: ${tiles.length}');  // prints the length of tiles correctly
    return Scaffold(
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          setState(() {
            tiles.add(ListTile(title: Text('Hello ${tiles.length+1}')));
          });
        },
      ),
      body: ListView(children: tiles),
    );
  }
}

Solution

  • Like @LonelyWolf said: You should use a ListView.builder and add Strings to your List instead of widgets

    class Home extends StatefulWidget {
      @override
      _HomeState createState() => _HomeState();
    }
    
    class _HomeState extends State<Home> {
      List<String> tiles = [];
    
      @override
      Widget build(BuildContext context) {
        print('length of tiles: ${tiles.length}');  // prints the length of tiles correctly
        return Scaffold(
          floatingActionButton: FloatingActionButton(
            onPressed: () {
              setState(() {
                tiles.add("${tiles.length+1}");
              });
            },
          ),
          body: ListView.builder(
            itemCount: tiles.length,
            itemBuilder: (_, index){
              return ListTile(
                title: Text('Hello ${tiles[index]}'),
              );
            },
          ),
        );
      }
    }