【发布时间】:2021-05-21 00:11:59
【问题描述】:
我有一个 FutureBuilder 从 Firestore 获取特定项目并将它们返回到列表中。为了更新这个列表,我添加了 RefreshIndicator。当将某些内容添加到列表中并刷新它时,它可以正常工作并出现该项目。当我从列表中删除一个项目时会出现问题,它会加载但列表保持不变。
这是我的小部件:
@override
void initState() {
super.initState();
userFuture = getCollectionItems();
}
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
body: Column(
children: [
Container(
margin: EdgeInsets.only(top: 5.5),
padding: EdgeInsets.only(left: 17, right: 17),
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Text(
"Collection",
style: TextStyle(
fontFamily: 'Montserrat',
fontSize: 28,
fontWeight: FontWeight.w800,
),
),
],
),
),
createGridAndList(),
Expanded(
child: RefreshIndicator(
onRefresh: () => getCollectionItems(),
child: displayCollection(),
),
)
],
),
);
}
当我重新启动应用程序或转到另一个页面并返回 pushNamedRemoveUntil 列表正确更新时,这表明查询正在运行。
getCollectionItems() 和 displayCollection():
getCollectionItems() async {
QuerySnapshot querySnapshot = await Firestore.instance
.collection("users")
.document(_userId)
.collection("userCollection")
.getDocuments();
List<Users> collectionID = [];
for (DocumentSnapshot item in querySnapshot.documents) {
var data = item.data;
Users user = Users();
user.id = data["id"];
collectionID.add(user);
}
final collectionIDs = collectionID.map((doc) => doc.id).toList();
var splitCollection = partition<dynamic>(collectionIDs, 10);
for (int i = 0; i < splitCollection.length; i++) {
QuerySnapshot querySnapshotCollections = await Firestore.instance
.collection('items')
.where('itemId', whereIn: splitCollection.elementAt(i))
.orderBy('timestamp', descending: true)
.getDocuments();
setState(() {
countItem = querySnapshotCollections.documents.length;
itemsList = querySnapshotCollections.documents
.map((documentSnapshot) =>
CollectionItem.fromDocument(documentSnapshot))
.toList();
});
}
}
displayCollection() {
return FutureBuilder(
future: userFuture,
builder: (context, snapshot) {
if (snapshot.connectionState != ConnectionState.done) {
return Padding(
padding: EdgeInsets.only(top: 20),
child: SizedBox(
child: CircularProgressIndicator(
valueColor: new AlwaysStoppedAnimation<Color>
(Colors.grey),
),
width: 20.0,
height: 20.0,
),
);
}
if (itemsList == null) {
return Container(
padding: EdgeInsets.only(top: 20),
child: SizedBox(
child: CircularProgressIndicator(
valueColor: new AlwaysStoppedAnimation<Color>
(Colors.grey),
),
width: 20.0,
height: 20.0,
),
);
} else if (itemsList.isEmpty) {
return ListView(
physics: const BouncingScrollPhysics(
parent: AlwaysScrollableScrollPhysics()),
children: [
Center(
child: Container(
padding: EdgeInsets.only(
top: MediaQuery.of(context).size.width * 0.50,
left: 17,
right: 17),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
"Nothing here.",
style: TextStyle(
fontFamily: 'Montserrat',
fontSize: 13,
color: Color(0xff9e9999),
fontWeight: FontWeight.w500),
textAlign: TextAlign.center,
),
],
),
),
),
],
);
} else if (itemOrientation == "grid") {
List<GridTile> gridTilesList = [];
itemsList.forEach((eachItem) {
gridTilesList.add(GridTile(child:
CollectionItemTile(eachItem)));
});
return GridView.count(
crossAxisCount: 2,
padding: EdgeInsets.fromLTRB(10, 15, 10, 0),
childAspectRatio: 3 / 2,
mainAxisSpacing: 15,
crossAxisSpacing: 10,
shrinkWrap: true,
physics: const BouncingScrollPhysics(
parent: AlwaysScrollableScrollPhysics()),
children: gridTilesList,
);
} else {
return Container(
padding: EdgeInsets.only(bottom: 15),
child: ListView(
padding: EdgeInsets.all(0.0),
shrinkWrap: true,
physics: const BouncingScrollPhysics(
parent: AlwaysScrollableScrollPhysics()),
children: itemsList),
);
}
});
}
我尝试了几件事,切换到 Stream(它不起作用),向 Widget 本身添加了另一个 setState,重建了类,但问题仍然存在。
【问题讨论】:
-
尝试向列表小部件添加一个键
-
我不知道我这样做是否正确但没有奏效。我将
key: UniqueKey()添加到ListView。你能告诉我你会怎么做吗? -
尝试添加 GlobalKey() 吗?
-
没用。
-
异步处理在我看来确实很可疑,但可能没问题。创建一个新属性
UniqueKey key;(您可能需要对其进行初始化),并在setState回调中尝试key = UniqueKey();getCollectionItems并确保FutureBuilder具有key: key这样当setState被调用时与FutureBuilder关联的State对象被替换。它可能会起作用。
标签: flutter flutter-futurebuilder