为ListView异步构建窗口小部件的颤振问题

时间:2020-07-31 11:59:13

标签: firebase flutter dart google-cloud-firestore

我想从Firestore查询图像并将其显示在我的应用中。 使用以下代码可以很好地显示一张图像:

Future<Widget> _getImage(BuildContext context) async {
    try {
      Image img;
      await FireStorageService.loadImage(context,
          '/Stände/' + standName + '/' + currentDate + '/hallo.jpg')
          .then((downloadUrl) {
        img = Image.network(
          downloadUrl.toString(),
          fit: BoxFit.scaleDown,
        );});
        return img;     
    } catch (err) {
      print(err);
    }
  }

  static Future<dynamic> loadImage(BuildContext context, String image) async {
    return await FirebaseStorage.instance.ref().child(image).getDownloadURL();
  }


        child: FutureBuilder(
          future: _getImage(context),
          builder: (context, snapshot) {
            if (snapshot.connectionState == ConnectionState.done)
              return SingleChildScrollView(
                child: Column(
                  children: <Widget>[
                    Container(
                      height: MediaQuery.of(context).size.height / 1.25,
                      width: MediaQuery.of(context).size.width / 1.25,
                      child: snapshot.data,
                    ),
                  ],
                ),
              );
            if (snapshot.connectionState == ConnectionState.waiting)
              return Container(
                  height: MediaQuery.of(context).size.height / 1.25,
                  width: MediaQuery.of(context).size.width / 1.25,
                  child: CircularProgressIndicator());

            return Container(child: Text('some error'));
          },
        ),
      ),

但是,如果我将我的图像创建包装成一个循环,它什么也不会显示。 我没有收到任何错误消息,如果我在存储小部件的位置打印了列表,它会显示我的图像,而这些图像不会显示在屏幕上。

Future<Widget> _getImage(BuildContext context) async {
    try {
      CollectionReference _documentRef = Firestore.instance
          .collection('Stände')
          .document('Testing')
          .collection(currentDate)
          .document(standName)
          .collection('images');
      Image img;
      List<Widget> imgList = [];
      _documentRef.getDocuments().then((ds) {
        ds.documents.forEach((value) async{
          await FireStorageService.loadImage(context,
                  '/Stände/' + standName + '/' + currentDate + '/hallo.jpg')
              .then((downloadUrl) {
            img = Image.network(
              downloadUrl.toString(),
              fit: BoxFit.scaleDown,
            );
            imgList.add(img);
          });
          print('${imgList}');
          return ListView.builder(
              itemCount: imgList.length,
              itemBuilder: (context, index) {
                return imgList[index];
              });
        });
      });
    } catch (err) {
      print(err);
    }
  }

我怀疑异步循环正在引起问题:

      _documentRef.getDocuments().then((ds) {
        ds.documents.forEach((value) async{

但是我只是不明白为什么它不起作用。 非常感谢您的帮助!

1 个答案:

答案 0 :(得分:1)

您将返回forEach函数内部。 _getImage实际上什么也不返回。

Future<Widget> _getImage(BuildContext context) async {
  try {
    // ...
    ds = await _documentRef.getDocuments();
    for (var doc in ds) {
      var downloadUrl = await FireStorageService.loadImage(
         context,
         '/Stände/' + standName + '/' + currentDate + '/hallo.jpg',
      );
      img = Image.network(
        downloadUrl.toString(),
        fit: BoxFit.scaleDown,
      );
      imgList.add(img);
    }

    // Now function is returning a widget
    return ListView.builder(
      itemCount: imgList.length,
      itemBuilder: (context, index) {
        return imgList[index];
      },
    );
  } catch (error) {
    // Error handing
  }
}