Flutter Streambuilder映射到列表对象

时间:2020-01-03 06:40:34

标签: flutter google-cloud-firestore

我需要在Flutter中显示列表视图,其中包含来自Firestore的数据。然后,我希望用户能够通过在应用栏的文本字段中键入查询来过滤listview。这是我为listview想到的代码:

_buildAllAds() {

  return StreamBuilder(
    stream: Firestore.instance.collection("Classificados")
    .orderBy('title').snapshots().map((snap) async {
      allAds.clear();
      snap.documents.forEach((d) {
        allAds.add(ClassificadoData(d.documentID,
          d.data["title"], d.data["description"], d.data["price"], d.data["images"] ));
       
      });

    }),
    builder: (context, snapshot) {

      // if (!snapshot.hasData) {
      //  return Center(child: CircularProgressIndicator());
      //  }
      //else{
      //}
      if (snapshot.hasError) {
        print("err:${snapshot.error}");
      }
      
      return ListView.builder(
        itemCount: allAds.length,
        itemBuilder: (context, index) {
          ClassificadoData ad = allAds[index];
          return ClassificadosTile(ad);

        });
    });

}

之所以将流数据保存在类型为ClassificadoData的列表 allAds (数据项是广告)中的原因是,然后我可以将其复制到另一个列表中,将其复制到 filteredAds 用户可以执行过滤。我之所以需要流 allAds 的原因是,我希望用户能够实时查看添加/更新。 因此,此代码“有效”,但感觉有点尴尬,并且我也无法对构建器执行任何操作,因为snaphot始终为null(例如,在初始数据获取期间无法显示加载器)。 想知道是否有一种更可靠的方式来做我想做的事,以及是否有可能将快照的参考传给建造者。

1 个答案:

答案 0 :(得分:2)

您似乎在混用使用Streams和与Stream相关的Widget的两种不同概念。理想情况下,您要么使用StreamBuilder并直接在Widget上使用从流中获取的数据,要么侦听数据并更新变量,然后将其用于填充ListView。我从您的代码中构建了后者作为示例:

@override
initState(){
  _listenToData();
  super.initState();
}

_listenToData(){
  Firestore.instance.collection("Classificados")
    .orderBy('title').snapshots().listen((snap){
    allAds.clear();
    setState(() {
      snap.documents.forEach((d) {
        allAds.add(ClassificadoData(d.documentID,
          d.data["title"], d.data["description"], d.data["price"], d.data["images"] ));
      });
    });
  });
}

_buildAllAds() {
  return ListView.builder(
    itemCount: allAds.length,
    itemBuilder: (context, index) {
      ClassificadoData ad = allAds[index];
      return ClassificadosTile(ad);
    }
  );
}