我是Flutter的新手,正在尝试在我的项目中使用FutureBuilder。我正在尝试使用Cloud Firestore中的元素列表构建ListView,因此我正在使用异步函数来获取数据,并使用FutureBuilder在加载之前为我提供一个占位符。不幸的是,当我检查snapshot.connectionState == ConnectionState.done时,该视图将在列表完全填充之前加载,并且我仅获得所需的元素之一。
我尝试实现Future.delay来尝试给列表填充时间。我还尝试了打印的方式(在下面的代码中标记),以查看是否所有元素都已从数据库中提取(它们是)。我还尝试在initState()中初始化Future,但是很可能实现错误。
class PlayersFragment extends StatefulWidget {
@override
State<StatefulWidget> createState() {
return PlayerFragStateChanged();
}
}
class PlayerFragStateChanged extends State<PlayersFragment> {
Widget build(BuildContext context) {
return
... //other items
FutureBuilder(
future: DataProvider().getPlayerList(),
builder: (BuildContext context,
AsyncSnapshot snapshot) {
if (snapshot.connectionState == ConnectionState.done){
return Expanded(
child: ListView.builder(
itemBuilder: (context, position) {
return Padding(
padding:
const EdgeInsets.only(
left: 20, top: 14),
child: Row(
children: <Widget>[
Text(snapshot.data[position].firstName),
Text(snapshot.data[position].lastName),
Text(BoolDecider().decide(snapshot.
data[position].amta)),
),
],
),
);
},
itemCount: snapshot.data.length
));
} else {
return Text('Waiting for data...');
}
... //other items
}
}
class DataProvider {
Firestore db = firestore();
Future<List<MockPlayer>> getPlayerList() async {
var result = await db.collection('Users').get();
var dataList = List<MockPlayer>();
result.forEach((doc) async {
debugPrint(doc.get('First name')); //Prints EVERY name in the database (as it should)
dataList.add(MockPlayer(
await doc.get('First name'),
await doc.get('Last name'),
await doc.get('AMTA Status'),
await doc.get('Phone number'),
await doc.get('email'),
await doc.get('ID')));
});
return dataList;
}
}
class BoolDecider {
String decide(bool i) {
if (i) {
return 'Yes';
} else {
return 'No';
}
}
}
我希望FutureBuilder可以打印多行,但是FutureBuilder的AsyncSnapshot中列表的长度仅为一,而它的长度应该大于一。
同样,当我执行result.forEach时,它会遍历数据库的每个成员。
任何帮助将不胜感激!
答案 0 :(得分:0)
问题出在您的forEach语句中。在您的future.connectionState设置为done之后,带有“异步”功能的forEach完成。这是通过替换来解决的:
result.forEach((doc) async {
dataList.add(MockPlayer(
await .. await .. await ..);
});
具有:
await Future.forEach(result, (doc) async {
dataList.add(MockPlayer(
await .. await .. await ..);
});
另外,根据Pedantic Dart所说,您不要忘记检查以下内容:
snapshot.hasData && !snapshot.hasError
。
答案 1 :(得分:0)
另一种有效的方法是替换
result.forEach((doc) async {
dataList.add(MockPlayer(
await .. await .. await ..);
});
与
for(final doc in result) async {
dataList.add(MockPlayer(
await .. await .. await ..);
});