我正在尝试与未来的构建者一起在我的应用中显示列表项。显示“正在等待结果...”大约0.5秒钟,然后仅显示白屏。当我用文本替换Listview时,文本显示为预期的样子。因此,它与我猜想的快照有关...
Widget buildList() {
return new FutureBuilder<List<CartItem>> (
future: getCartItems(),
builder: (context, snapshot) {
switch (snapshot.connectionState) {
case ConnectionState.none:
return new Text('Press button to start');
case ConnectionState.waiting:
return new Text('Awaiting result...');
default:
print(snapshot.data);
print(snapshot.hasData);
return
(!snapshot.hasData)
?
new Container(
alignment: FractionalOffset.center,
child: new CircularProgressIndicator())
:
new ListView(
children: snapshot.data,
);
}});
}}
这是我的 getCartItems :
Future<List<CartItem>> getCartItems() async {
final FirebaseUser user = await FirebaseAuth.instance.currentUser();
final uid = user.uid;
List<CartItem> cartItems = [];
QuerySnapshot data = await Firestore.instance
.collection("carts")
.where('owner', isEqualTo: uid)
.where('active', isEqualTo: true)
.getDocuments();
data.documents.forEach((DocumentSnapshot doc) async {
var keys = doc["products"].keys.toList();
var values = doc["products"].values.toList();
for (var i = 0; i < keys.length; i++){
await Firestore.instance.collection('products').document(keys[i]).get().then((DocumentSnapshot ds) {
cartItems.add( new CartItem.fromDocument(ds, values[i]));
print(cartItems);
});
}
});
return cartItems;
}
我知道Futurebuilder被两次调用: https://github.com/flutter/flutter/issues/18490
但是我不知道如何处理这种情况...
有什么想法吗?在这种情况下,我真的需要FutureBuilder吗?
编辑:
我在buildList小部件中添加了一些打印,并显示以下输出:
Performing hot reload...
Reloaded 5 of 710 libraries in 808ms.
I/flutter (23685): [] <--- snapshit.data
I/flutter (23685): true <--- snapshot.hasData
编辑2:
已更改,但仍无法正常工作:
Future<List<CartItem>> getCartItems() async {
final FirebaseUser user = await FirebaseAuth.instance.currentUser();
final uid = user.uid;
List<CartItem> cartItems = [];
QuerySnapshot data = await Firestore.instance
.collection("carts")
.where('owner', isEqualTo: uid)
.where('active', isEqualTo: true)
.getDocuments();
cartItems = await _fetchDocumentData(data);
return cartItems;
}
Future<List<CartItem>> _fetchDocumentData(data) async {
List<CartItem> cartItems = [];
data.documents.forEach((DocumentSnapshot doc) {
var keys = doc["products"].keys.toList();
var values = doc["products"].values.toList();
for (var i = 0; i < keys.length; i++){
Firestore.instance.collection('products').document(keys[i]).get().then((DocumentSnapshot ds) {
cartItems.add( new CartItem.fromDocument(ds, values[i]));
print(cartItems);
});
}
});
return cartItems;
}
编辑3:
控制台中的输出看起来像Futurebuilder在获取完成之前已执行:
I/flutter ( 4535): [] <--- print(snapshot.data) in FutureBuilder
I/flutter ( 4535): true <--- print(snapshot.hasData) in FutureBuilder
I/flutter ( 4535): [CartItem] <--- print(cartItems) in _fetchDocumentData
答案 0 :(得分:1)
问题可能在这里:
new ListView(
children: snapshot.data,
);
参数children
以List<Widget>
作为参数。您直接将数据作为参数提供给它,因此它不会在UI上向您显示任何结果。
您可以使用ListView.builder
这样显示数据:
ListView.builder(
itemCount: snapshot.data.length,
itemBuilder: (context, position) {
var cartItem = snapshot.data[position];
return Row(
children: <Widget>[
Expanded(child: Text(cartItem.id)), // just for example
Expanded(child: Text(cartItem.name)), // just for example
Expanded(child: Text(cartItem.color)), // just for example
],
);
},
)
编辑:
将代码放入_fetchDocumentData
之类的方法中获取数据并声明该方法async
并具有Future<List<CartItem>>
这样的返回类型:
Future<List<CartItem>> _fetchDocumentData async {
List<CartItem> cartItems = [];
data.documents.forEach((DocumentSnapshot doc) {
var keys = doc["products"].keys.toList();
var values = doc["products"].values.toList();
for (var i = 0; i < keys.length; i++){
await Firestore.instance.collection('products').document(keys[i]).get().then((DocumentSnapshot ds) {
cartItems.add( new CartItem.fromDocument(ds, values[i]));
print(cartItems);
});
}
});
return cartItems;
}
并且在返回cartItems
之前,先从cartItems
提取_fetchDocumentData
cartItems = await _fetchDocumentData();
说明: 您的循环是异步的,因此在循环执行完成之前会返回值。
编辑::您在此处询问的是可能要进行的代码更改。
更改此内容:
Future<List<CartItem>> getCartItems() async {
final FirebaseUser user = await FirebaseAuth.instance.currentUser();
final uid = user.uid;
List<CartItem> cartItems = [];
QuerySnapshot data = await Firestore.instance
.collection("carts")
.where('owner', isEqualTo: uid)
.where('active', isEqualTo: true)
.getDocuments();
data.documents.forEach((DocumentSnapshot doc) async {
var keys = doc["products"].keys.toList();
var values = doc["products"].values.toList();
for (var i = 0; i < keys.length; i++){
await Firestore.instance.collection('products').document(keys[i]).get().then((DocumentSnapshot ds) {
cartItems.add( new CartItem.fromDocument(ds, values[i]));
print(cartItems);
});
}
});
return cartItems;
}
为此:
Future<List<CartItem>> getCartItems() async {
final FirebaseUser user = await FirebaseAuth.instance.currentUser();
final uid = user.uid;
List<CartItem> cartItems = [];
QuerySnapshot data = await Firestore.instance
.collection("carts")
.where('owner', isEqualTo: uid)
.where('active', isEqualTo: true)
.getDocuments();
cartItems = await _fetchDocumentData();
return cartItems;
}
Future<List<CartItem>> _fetchDocumentData async {
List<CartItem> cartItems = [];
data.documents.forEach((DocumentSnapshot doc) {
var keys = doc["products"].keys.toList();
var values = doc["products"].values.toList();
for (var i = 0; i < keys.length; i++){
await Firestore.instance.collection('products').document(keys[i]).get().then((DocumentSnapshot ds) {
cartItems.add( new CartItem.fromDocument(ds, values[i]));
print(cartItems);
});
}
});
return cartItems;
}