Flutter:使用来自 Firestore 的数据生成一个 Widget 列表
Flutter: generate a List of Widgets with data from Firestore
我希望我的屏幕显示 GridView
中有限数量的产品。
所有产品都存储在 Firebase Firestore 中,它们的图像在 Firebase 存储中。
为此,我使用 GridView.count
,它的参数之一是 List<Widget> children
。我想使用 List.generate
生成一个列表,每次都从 Firestore 中获取一个产品,并从存储中获取它的图像,以创建一个代表产品的小部件。
问题是从 Firebase 中获取产品是异步的,List.generate
的 generator
函数不能是 async
。此外,我将 Future<List<Widget>>
而不是 List<Widget>
返回到 GridView.count
的 children
参数
关于如何克服这个问题的任何想法?
这是我的代码:
GridView.count(
primary: false,
crossAxisCount: 2,
padding: const EdgeInsets.all(20),
crossAxisSpacing: 10,
mainAxisSpacing: 10,
//FIXME: The argument type 'Future<List<Widget>>' can't be assigned to the parameter type 'List<Widget>':
children: _buildGridTileList(15),
)
Future<List<Widget>> _buildGridTileList(int count) async {
var counterCollection = await FirebaseFirestore.instance.collection("Products").doc("Counter").get();
var counterData = counterCollection.data();
return List.generate(
count,
(index) async {
//FIXME: Doesn't work beacuse generator cannot be async!!
var avatarUrl = await FirebaseStorage.instance.ref('${counterData[index]}').child('${counterData[index]}').getDownloadURL();
return Container(
child: Center(
child: NetworkImage(avatarUrl),
),
);
}
);
}
您的构建函数中不能有异步代码,因为它是组装小部件树以立即呈现到屏幕的函数,而您所做的是使用 StreamBuilder 小部件,它使您可以访问异步事件、流正在侦听来自 Firebase 的未来数据,并在异步事件到达时重建小部件树的该部分。这是它是如何完成的,这段代码应该接近你所需要的:
return StreamBuilder(
stream: FirebaseFirestore.instance.collection("Products").snapshots(),
builder:
(BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) {
if (!snapshot.hasData) {
return Container();
} else {
return GridView.count(
primary: false,
crossAxisCount: 2,
padding: const EdgeInsets.all(20),
crossAxisSpacing: 10,
mainAxisSpacing: 10,
children: List.generate(snapshot.data.docs.length, (index) {
return Image.network(snapshot.data.docs[index].imageUrl);
}),
);
}
});
}
我希望我的屏幕显示 GridView
中有限数量的产品。
所有产品都存储在 Firebase Firestore 中,它们的图像在 Firebase 存储中。
为此,我使用 GridView.count
,它的参数之一是 List<Widget> children
。我想使用 List.generate
生成一个列表,每次都从 Firestore 中获取一个产品,并从存储中获取它的图像,以创建一个代表产品的小部件。
问题是从 Firebase 中获取产品是异步的,List.generate
的 generator
函数不能是 async
。此外,我将 Future<List<Widget>>
而不是 List<Widget>
返回到 GridView.count
的 children
参数
关于如何克服这个问题的任何想法?
这是我的代码:
GridView.count(
primary: false,
crossAxisCount: 2,
padding: const EdgeInsets.all(20),
crossAxisSpacing: 10,
mainAxisSpacing: 10,
//FIXME: The argument type 'Future<List<Widget>>' can't be assigned to the parameter type 'List<Widget>':
children: _buildGridTileList(15),
)
Future<List<Widget>> _buildGridTileList(int count) async {
var counterCollection = await FirebaseFirestore.instance.collection("Products").doc("Counter").get();
var counterData = counterCollection.data();
return List.generate(
count,
(index) async {
//FIXME: Doesn't work beacuse generator cannot be async!!
var avatarUrl = await FirebaseStorage.instance.ref('${counterData[index]}').child('${counterData[index]}').getDownloadURL();
return Container(
child: Center(
child: NetworkImage(avatarUrl),
),
);
}
);
}
您的构建函数中不能有异步代码,因为它是组装小部件树以立即呈现到屏幕的函数,而您所做的是使用 StreamBuilder 小部件,它使您可以访问异步事件、流正在侦听来自 Firebase 的未来数据,并在异步事件到达时重建小部件树的该部分。这是它是如何完成的,这段代码应该接近你所需要的:
return StreamBuilder(
stream: FirebaseFirestore.instance.collection("Products").snapshots(),
builder:
(BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) {
if (!snapshot.hasData) {
return Container();
} else {
return GridView.count(
primary: false,
crossAxisCount: 2,
padding: const EdgeInsets.all(20),
crossAxisSpacing: 10,
mainAxisSpacing: 10,
children: List.generate(snapshot.data.docs.length, (index) {
return Image.network(snapshot.data.docs[index].imageUrl);
}),
);
}
});
}