Search code examples
flutterflutter-circularprogressindicator

CircularProgressIndicator value not updated


For the code shown below, I think that just calculating a new value for _progress should cause the CircularProgressIndicator to redraw. That does not appear to be happening. It never updates, although I have verified in the debugger that _progress is changed.

What do I need to do to get it to update?

      int completed = 0;
      int total = list.length;
      double _progress = 0;

      showDialog(context: this.context, builder: (BuildContext context) {
        return AlertDialog(
          title: const Text('Downloading ...'),
          content: CircularProgressIndicator(
            value: _progress));
      });
      for (FileInfo fileInfo in list) {
        if(fileInfo.publicUrl != null) {
          var filename = dir!.path + '/' + fileInfo.name!;
          await dio.download(fileInfo.publicUrl!, filename);
          completed++;
          _progress = completed/total;
        }
      }


Solution

  • The problem here is that the CircularProgressIndicator is not updating because the widget tree is not being notified of the changes in the _progress variable. Simply changing the value of a variable does not automatically cause the widgets to redraw. You need to inform the framework that a change has occurred and that it needs to rebuild the relevant widgets.

    A solution is to wrap the AlertDialog in a StatefulBuilder and call setState after updating the _progress variable.

    First ensure that the code you provided is in a StatefulWidget, then make changes as shown below:

    int completed = 0;
    int total = list.length;
    double _progress = 0;
    
    showDialog(context: this.context, builder: (BuildContext context) {
      return StatefulBuilder(
        builder: (BuildContext context, StateSetter setState) {
          return AlertDialog(
            title: const Text('Downloading ...'),
            content: CircularProgressIndicator(value: _progress),
          );
        },
      );
    });
    
    for (FileInfo fileInfo in list) {
      if(fileInfo.publicUrl != null) {
        var filename = dir!.path + '/' + fileInfo.name!;
        await dio.download(fileInfo.publicUrl!, filename);
        completed++;
        setState(() {
          _progress = completed / total;
        });
      }
    }