我想通过按钮onPressed
更改Firestore中的值。我知道可能会有几秒钟的延迟,所以我想在等待时显示一个CircularProgressIndicator
小部件。但这是行不通的。
这是我的小部件:
Widget save(String id) {
return new FutureBuilder(
future: PostController().isAlreadySaved(id),
builder: (BuildContext context, AsyncSnapshot<bool> snapshot) {
if (snapshot.hasData) {
if (snapshot.data) {
return FlatButton(
onPressed: () {
setState(() {
isSaveLoading = true;
});
PostController().deleteSaved(id);
setState(() {
isSaveLoading = false;
});
},
child: !isSaveLoading
? Icon(
MyFlutterApp.star,
size: 30,
color: Colors.redAccent,
)
: SizedBox(
height: 15,
width: 15,
child: CircularProgressIndicator(
strokeWidth: 1,
),
),
);
} else {
return FlatButton(
onPressed: () {
setState(() {
isSaveLoading = true;
});
PostController().save(context, id);
setState(() {
isSaveLoading = false;
});
},
child: !isSaveLoading
? Icon(
MyFlutterApp.star,
size: 30,
color: Colors.grey,
)
: SizedBox(
height: 15,
width: 15,
child: CircularProgressIndicator(
strokeWidth: 1,
),
),
);
}
} else {
return Container(
//color: Colors.white,
width: Adapt.screenW(),
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Flexible(
child: Shimmer.fromColors(
baseColor: Colors.grey[400],
highlightColor: Colors.grey[50],
enabled: true,
child: Row(
children: <Widget>[
Padding(
padding: const EdgeInsets.fromLTRB(5, 0, 0, 0),
child: new Icon(
MyFlutterApp.star,
size: 30,
color: Colors.white,
),
),
],
),
),
),
],
),
);
}
},
);
}
这是我的isAlreadySaved()
函数:
Future<bool> isAlreadySaved(String id) async {
bool isSaved = false;
QuerySnapshot snapshot =
await databaseReference.collection('saved').getDocuments();
snapshot.documents.forEach((a) async {
if (a.data['postID'] == id&&
a.data['saver'] == globals.currentUser.uid) {
isSaved = true;
}
});
return isSaved;
}
删除功能实际上是从我在firestore中保存的集合中删除文档,而保存功能会创建一个文档并保存。
提前谢谢!
答案 0 :(得分:1)
我认为问题是因为您太快地更新了窗口小部件树,或者是通过等待PostController
作业完成来使浮动的UI线程被锁定...
在这些行中:
onPressed: () {
setState(() {
isSaveLoading = true;
});
PostController().deleteSaved(id);
setState(() {
isSaveLoading = false;
});
},
在这里,我看到您要更新按钮的正在加载状态。但是问题在于,当您将isSaveLoading
设置为true
时,您不会等到PostController().deleteSaved(id)
完成之后再将isSaveLoading
重置为false
。
另一方面,如果PostController().deleteSaved()
做得很长,由于它不是异步的,它可以锁定UI线程一段时间,因此您将永远看不到循环进度条。
您可以使onPressed
回调异步,并等待PostController
的工作。
onPressed: () async {
setState(() {
isSaveLoading = true;
});
// The deleteSaved function have to be async too
await PostController().deleteSaved(id);
setState(() {
isSaveLoading = false;
});
},
希望这会有所帮助!