简体   繁体   中英

How to show Circular progress indicator while fetching document from Firestore

Here is how I am trying to read data from a single document in Firestore.

final CollectionReference myCollection =
  FirebaseFirestore.instance.collection('collection');
//
Future getScore(String level) async {
  var document = await myCollection.doc(uid).get();
  for (int i = 0; i < document.data().length; i++) {
    print(document.data().keys.elementAt(i));
    print(document.data().values.elementAt(i));
  }
}

I call this code on press of a button like this:

Expanded(
    flex: 1,
    child: Container(
      alignment: Alignment.centerLeft,
      child: ElevatedButton(
        onPressed: () {
          //////////////////////////////////////////////////////////////////////
          // This is where I call the getScore function in database dart file //
          //////////////////////////////////////////////////////////////////////
          DatabaseService(uid: globals.uid).getScore(
          'level11',
          );
          /////////////////////////////////////////////////////////////////////////////////////////////////
          // I would like the circular indicator until data is fetched and before the new view is pushed //
          /////////////////////////////////////////////////////////////////////////////////////////////////
          Navigator.push(
              context,
              CupertinoPageRoute(
                  builder: (context) => GameHome()));
        },
        child: Text(
          'Play',
          style: Theme.of(context).textTheme.headline2,
        ),
        style: OutlinedButton.styleFrom(
          shape: StadiumBorder(),
          padding: EdgeInsets.symmetric(
              horizontal: 5.25 * SizeConfig.textMultiplier,
              vertical: 1.125 * SizeConfig.textMultiplier),
          side: BorderSide(width: 1, color: Colors.black26),
          backgroundColor: Colors.black,
        ),
      ),
    ),
  ),

I was wondering how can I show the circular progress indicator until the data is fetched and the view switch code is executed.

Thanks for any pointers.

Make your Widget a StatefullWidget and set a boolean value isLoading to false . Make sure that your DatabaseService is asynchronous and await it. If the value of isLoading is true show a CircularProgressIndicator.

Here is a basic example:

import 'package:flutter/material.dart';

class YourWidget extends StatefulWidget {
  @override
  _YourWidgetState createState() => _YourWidgetState();
}

class _YourWidgetState extends State<YourWidget> {
  bool isLoading = false;

  Future getScore() async {
    setState(() {
      isLoading = true;
    });
    //////////////////////////////////////////////////////////////////////
    // This is where I call the getScore function in database dart file //
    //////////////////////////////////////////////////////////////////////
    await DatabaseService(uid: globals.uid).getScore(
      'level11',
    );
    /////////////////////////////////////////////////////////////////////////////////////////////////
    // I would like the circular indicator until data is fetched and before the new view is pushed //
    /////////////////////////////////////////////////////////////////////////////////////////////////

    setState(() {
      isLoading = false;
    });

    Navigator.push(
        context, CupertinoPageRoute(builder: (context) => GameHome()));
  }

  @override
  Widget build(BuildContext context) {
    return Expanded(
      flex: 1,
      child: Container(
        alignment: Alignment.centerLeft,
        child: Column(
          children: [
            ElevatedButton(
              onPressed: getScore,
              child: Text(
                'Play',
                style: Theme.of(context).textTheme.headline2,
              ),
              style: OutlinedButton.styleFrom(
                shape: StadiumBorder(),
                padding: EdgeInsets.symmetric(
                    horizontal: 5.25 * SizeConfig.textMultiplier,
                    vertical: 1.125 * SizeConfig.textMultiplier),
                side: BorderSide(width: 1, color: Colors.black26),
                backgroundColor: Colors.black,
              ),
            ),
            Visibility(visible: isLoading, child: CircularProgressIndicator())
          ],
        ),
      ),
    );
  }
}


Make your Widget a StatefullWidget and set a boolean value isLoading to false . Make sure that your DatabaseService is asynchronous and await it. If the value of isLoading is true show a CircularProgressIndicator. Edit: You don't need to setState(){isLoading=false} because once you push to a new screen the state will be updated. Thus avoids building the screen everytime Here is a basic example:

import 'package:flutter/material.dart';

class YourWidget extends StatefulWidget {
  @override
  _YourWidgetState createState() => _YourWidgetState();
}

class _YourWidgetState extends State<YourWidget> {
  bool isLoading = false;

  Future getScore() async {
    setState(() {
      isLoading = true;
    });
    //////////////////////////////////////////////////////////////////////
    // This is where I call the getScore function in database dart file //
    //////////////////////////////////////////////////////////////////////
    await DatabaseService(uid: globals.uid).getScore(
      'level11',
    );
    /////////////////////////////////////////////////////////////////////////////////////////////////
    // I would like the circular indicator until data is fetched and before the new view is pushed //
    /////////////////////////////////////////////////////////////////////////////////////////////////

 

    Navigator.push(
        context, CupertinoPageRoute(builder: (context) => GameHome()));
  }

  @override
  Widget build(BuildContext context) {
    return Expanded(
      flex: 1,
      child: Container(
        alignment: Alignment.centerLeft,
        child: Column(
          children: [
            ElevatedButton(
              onPressed: getScore,
              child: Text(
                'Play',
                style: Theme.of(context).textTheme.headline2,
              ),
              style: OutlinedButton.styleFrom(
                shape: StadiumBorder(),
                padding: EdgeInsets.symmetric(
                    horizontal: 5.25 * SizeConfig.textMultiplier,
                    vertical: 1.125 * SizeConfig.textMultiplier),
                side: BorderSide(width: 1, color: Colors.black26),
                backgroundColor: Colors.black,
              ),
            ),
            Visibility(visible: isLoading, child: CircularProgressIndicator())
          ],
        ),
      ),
    );
  }
}


The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM