即使查询没有完成,Future Builder也会完成数据获取(Flutter Firestore)



我创建了一个flutter应用程序,它从多个来源、firestore数据库和一些HTTP API调用获取数据。我知道你需要时间将这些数据加载到应用程序中,所以我在FutureBuilder()上构建了我的小部件。然而,有时快照在加载所有数据之前就已经返回了数据。有人能帮我延长加载程序的动画,这样我的UI就不会出错了吗。非常感谢。

这是我的主要小工具:

  Widget build(BuildContext context) {
    print('this is homelist length: $homeList');
    return Scaffold(
      backgroundColor: AppTheme.white,
      body: FutureBuilder(
        future: getData(),
        builder: (context, snapshot) {
          if (!snapshot.hasData) {
            return Center(
              child: CircularProgressIndicator(
                strokeWidth: 3,
              ),
            );
          } else {
            return Padding(
              padding: EdgeInsets.only(top: MediaQuery.of(context).padding.top),
              child: Column(
                mainAxisAlignment: MainAxisAlignment.center,
                crossAxisAlignment: CrossAxisAlignment.start,
                children: <Widget>[
                  appBar(),
                  Expanded(
                    child: FutureBuilder(
                      future: getData2(),
                      builder: (context, snapshot) {
                        if (!snapshot.hasData) {
                          return Center(
                            child: CircularProgressIndicator(
                              strokeWidth: 3,
                            ),
                          );
                        } else {
                          return homeList.isEmpty == false
                              ? GridView(
                                  padding: EdgeInsets.only(
                                      top: 0, left: 12, right: 12),
                                  physics: BouncingScrollPhysics(),
                                  scrollDirection: Axis.vertical,
                                  children: List.generate(
                                    homeList.length,
                                    (index) {
                                      var count = homeList.length;
                                      var animation =
                                          Tween(begin: 0.0, end: 1.0).animate(
                                        CurvedAnimation(
                                          parent: animationController,
                                          curve: Interval(
                                              (1 / count) * index, 1.0,
                                              curve: Curves.fastOutSlowIn),
                                        ),
                                      );
                                      animationController.forward();
                                      return HomeListView(
                                        animation: animation,
                                        animationController:
                                            animationController,
                                        listData: homeList.elementAt(index),
                                        callBack: () {
                                          Navigator.push(
                                            context,
                                            MaterialPageRoute(
                                              builder: (context) => homeList
                                                  .elementAt(index)
                                                  .navigateScreen,
                                            ),
                                          );
                                        },
                                      );
                                    },
                                  ),
                                  gridDelegate:
                                      SliverGridDelegateWithFixedCrossAxisCount(
                                    crossAxisCount: multiple ? 2 : 1,
                                    mainAxisSpacing: 12.0,
                                    crossAxisSpacing: 12.0,
                                    childAspectRatio: 1.5,
                                  ),
                                )
                              : Container(
                                  margin: EdgeInsets.all(12),
                                  child: Column(
                                    children: <Widget>[
                                      SizedBox(
                                        height: 30,
                                      ),
                                      Container(
                                        decoration: BoxDecoration(
                                          color: AppTheme.white,
                                          borderRadius: BorderRadius.only(
                                              topLeft: Radius.circular(8.0),
                                              bottomLeft: Radius.circular(8.0),
                                              bottomRight: Radius.circular(8.0),
                                              topRight: Radius.circular(8.0)),
                                          boxShadow: <BoxShadow>[
                                            BoxShadow(
                                                color: AppTheme.grey
                                                    .withOpacity(0.8),
                                                offset: Offset(1.1, 1.1),
                                                blurRadius: 10.0),
                                          ],
                                        ),
                                        child: Column(
                                          children: <Widget>[
                                            Text(
                                                'Welcome to DiabeatIS, your patients will be displayed here!',
                                                style: AppTheme.headline,
                                                textAlign: TextAlign.justify),
                                            Divider(
                                              color: Colors.black,
                                            ),
                                            SizedBox(
                                              height: 15,
                                            ),
                                            Text(
                                              'Simply ask your patient for their code, and click the button below, you will be taken to a screen where you can add your patients, and view their data afterwards!',
                                              style: AppTheme.subtitle,
                                              textAlign: TextAlign.justify,
                                            ),
                                            RaisedButton(
                                              child: Text('Add Patients'),
                                              onPressed: () {
                                                Navigator.push(
                                                    context,
                                                    MaterialPageRoute(
                                                        builder: (context) =>
                                                            AddPatient()));
                                              },
                                            )
                                          ],
                                        ),
                                      ),
                                    ],
                                  ),
                                );
                        }
                      },
                    ),
                  ),
                ],
              ),
            );
          }
        },
      ),
    );
  }

以下是我的FutureBuilder的函数:

  Future<bool> getData2() async {
    await Future.delayed(Duration(milliseconds: 200));
    return true;
  }
  Future<bool> getData() async {
    _getCurrentUser();
    await Future.delayed(const Duration(milliseconds: 1000), () async {
      _getPatients(); // a function that involves two queries 
    });

    return true;
  }

获取患者功能:

  Future<bool> _getPatients() async {
    homeList.clear();
    if (didLoadpatients == 0) {
      print('this is didloadpatients at start of func $didLoadpatients');
      var document = await db
          .collection('users')
          .document(mUser.uid)
          .collection('patients');
      document.getDocuments().then((QuerySnapshot query) async {
        query.documents.forEach((f) {
          uids.add(f.data['uID']);
        });
        didLoadpatients++;
        print('this is didloadpatients at end of func $didLoadpatients');
        for (var i = 0; i < uids.length; i++) {
          var userDocuments = await db.collection('users').document(uids[i]);
          userDocuments.get().then((DocumentSnapshot doc) {
            homeList.add(HomeList(
                imagePath: 'assets/fitness_app/fitness_app.png',
                navigateScreen: DVFitnessAppHomeScreen(
                  uid: doc.data['userID'],
                ),
                patientInfo: new PatientInfo.fromFbase(doc.data)));
          });
          print(homeList);
        }
        print(homeList);
        var document = await db
            .collection('users')
            .document(mUser.uid)
            .collection('notifications')
            .where('hasbeenViewed', isEqualTo: false)
            .getDocuments();
        final List<DocumentSnapshot> notifDoc = document.documents;
        notifications = notifDoc.length;
        await Future.delayed(Duration(milliseconds: 800));
        return true;
      });
    } else
      print('I am leaving the get patient function');
    await Future.delayed(Duration(milliseconds: 800));
    return true;
  }

更新1:

看起来你所需要的只是await

 Future<bool> getData() async {
     await _getCurrentUser();
     await _getPatients();
    return true;
  }

您可以使用Future.wait一次等待多个未来。

Future.wait([future1, future2])

请参阅此处的文档。

最新更新