我需要在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(例如,在初始数据获取期间无法显示加载器)。 想知道是否有一种更可靠的方式来做我想做的事,以及是否有可能将快照的参考传给建造者。
答案 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);
}
);
}