Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to display a progress indicator for each async call FutureBuilder

Tags:

flutter

dart

Below I have a simple setup to demonstrate a Stateful Widget using a FutureBuilder. When the Future async call first fires we see the CircularProgressIndicator on the screen.

After the Future is complete we see the UI which includes a refresh FlatButton, when pressed setState is called to redraw the widgets.

The Future async function is called again but this time we do not see the CircularProgressIndicator because AsyncSnapshot.hasData is true.

This means that AsyncSnapshot.hasData has its value from the previous FutureBuilder build that completed.

How can I achieve have a "pure" refresh/purge of my UI Widgets so that my CircularProgressIndicator displays on each each async data call with each Refresh button press that calls setState?

import 'dart:async';
import 'package:flutter/material.dart';

class DemoFutureBuilder extends StatefulWidget {
  @override
  State<StatefulWidget> createState() => _DemoFutureBuilder();
}

class _DemoFutureBuilder extends State<DemoFutureBuilder> {
  var _displayText = 'Hello World';

  @override
  Widget build(BuildContext context) {
    return FutureBuilder(
        future: helloWorldAsync(),
        builder: (context, snapshot) {
          if (!snapshot.hasData) {
            print('=============== Snapshot no data ==========');
            return CircularProgressIndicator();
          }

          print('=============== Snapshot has data ==========');
          return Column(
            children: <Widget>[
              Text(snapshot.data),
              Padding(
                padding: EdgeInsets.only(top: 20),
                child: FlatButton(
                  child: Text('Pure & Clean Refresh'),
                  onPressed: () {
                    setState(() {
                      _displayText = 'Goodbye Cruel World';
                    });
                  },
                ),
              )
            ],
          );
        });
  }

  Future<String> helloWorldAsync() async {
    return Future<String>.delayed(Duration(seconds: 3)).then((_) {
      return _displayText;
    });
  }
}
like image 916
Brian Ogden Avatar asked May 24 '19 01:05

Brian Ogden


People also ask

How do async methods report progress?

Today, we’ll look at how async methods satisfy a common requirement of background operations: reporting progress. When asynchronous methods report progress, they use an abstraction of the “progress reporter” concept: IProgress<in T>. This interface has a single method: void Report (T value). You can’t get much simpler than that!

Where should the progress indicator be shown?

Ideally, the progress indicator is shown on top of everything, preventing the user from interacting with the UI. Let’s build a progress indicator that looks like this: What does Flutter provide?

What are Flutter’s progress indicators?

This is the first of Flutter’s inbuilt progress indicators, which is a subclass of the ProgressIndicator abstract class. It is used to communicate the progress of a task in a horizontal bar. This is the second of Flutter’s inbuilt progress indicators, and it is also a subclass of the ProgressIndicator abstract class.

What is async async/await?

Async/await will gently nudge you away from OOP and towards functional programming. This is natural and should be embraced. Now let’s look at the “receiving” side of progress reports. The caller of the asynchronous method passes in the progress reporter, so it has complete control of how progress reports are handled.


2 Answers

I was also having the same issue i have solved it using "snapshot.connectionState" you can check it as "ConnectionState.(waiting, done or active)" in your case where you are using snapshot.hasData add one more condition for checking connection state. this will solve your problem...

you can refer this for detials https://codinginfinite.com/flutter-future-builder-pagination/

like image 60
Shubham Mundra Avatar answered Nov 15 '22 07:11

Shubham Mundra


If you add a connection state check in your code like this:

if (!snapshot.hasData || snapshots.connectionState == ConnectionState.waiting) {
  print('=============== Snapshot no data ==========');
  return CircularProgressIndicator();
}

It should also show the progress indicator when your data gets refreshed.

like image 25
markus Avatar answered Nov 15 '22 06:11

markus