Flutter Listview after run empty, but filled only with Flutter Hot reload

Issue

How can I correct this code? That might have sparked the need to win another solution.

enter image description here
This result is only after a hot reload, and at the first start it is empty.

class PageOnes extends StatefulWidget {
  final String pageName;

  const PageOnes({
    required this.pageName,
    Key? key,
  }) : super(key: key);

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

class _PageOnesState extends State<PageOnes> {
  List<String> items = [];

  @override
  Widget build(BuildContext context)  {
    deviceInfo();

    return Scaffold(
      appBar: AppBar(
        title: Text(widget.pageName),
      ),
      body: ListView.separated(
          padding: const EdgeInsets.all(8),
          itemCount: items.length,
          itemBuilder: (context, index) {
            return ListTile(
              title: Text(items[index],style: const TextStyle(fontFamily: 'Proximal', fontSize: 18),
              ),
            );
          },
          separatorBuilder: (BuildContext context, int index) => const Divider(
                thickness: 5,
                endIndent: 10,
                indent: 10,
              )),
    );
  }

   void deviceInfo() async  {
    const int MEGABYTE = 1024 * 1024;
    DeviceInfoPlugin deviceInfoPlugin = DeviceInfoPlugin();
    AndroidDeviceInfo androidDeviceInfo = await deviceInfoPlugin.androidInfo;
    items.add('Brand: ${androidDeviceInfo.manufacturer}.');
     }
}

Solution

You are using future method, data isnt avialble on first frame , it will take some time to fetch data. Try using FutureBuilder

class _PageOnesState extends State<PageOnes> {
  Future<void> deviceInfo() async {
    List items = [];
    const int MEGABYTE = 1024 * 1024;
    DeviceInfoPlugin deviceInfoPlugin = DeviceInfoPlugin();
    AndroidDeviceInfo androidDeviceInfo = await deviceInfoPlugin.androidInfo;
    items.add('Brand: ${androidDeviceInfo.manufacturer}.');

    return items;
  }

  late final myFuture = deviceInfo();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.pageName),
      ),
      body: FutureBuilder(
        future: myFuture,
        builder: (context, snapshot) {
          if(snapshot.hasData){

            final items  = snapshot.data;

            return  ListView.separated(
            padding: const EdgeInsets.all(8),
            itemCount: items.length,
            itemBuilder: (context, index) {
              return ListTile(
                title: Text(
                  items[index],
                  style: const TextStyle(fontFamily: 'Proximal', fontSize: 18),
                ),
              );
            },
            separatorBuilder: (BuildContext context, int index) =>
                const Divider(
                  thickness: 5,
                  endIndent: 10,
                  indent: 10,
                )),
          }

          return CircularProgressIndicator();
        },
      ),
    );
  }
}

Not recommended but you can trick.

Dont call method directly inside build method. use intitState

  @override
  void initState() {
    super.initState();
    deviceInfo();
  }
 void deviceInfo() async  {
  .....
   setState((){});
     }

Answered By – Yeasin Sheikh

Answer Checked By – Mary Flores (FlutterFixes Volunteer)

Leave a Reply

Your email address will not be published. Required fields are marked *