问题描述
我正在使用FutureBuilder
从数据库调用中构建将来的项目列表。
由于某种原因,当我打电话给setState()
时,FutureBuilder
运行两次,这是有问题的。
我已经对代码进行了简化以说明问题:
void initState() {
super.initState();
futureIng = db.getIngredients();
}
Widget build(BuildContext context) {
return Column(
children: [
getButton(),getDeleteButton(),FutureBuilder<List<Ingredientsql>>(
future: futureIng,builder: (BuildContext context,AsyncSnapshot<List<Ingredientsql>> snapshot) {
if (snapshot.hasData && snapshot.data != null) {
if (snapshot.data.isEmpty) {
return Text("nothing yet",style: TextStyle(color: Colors.white));
}
return Text(getList(snapshot.data));
} else {
return CircularProgressIndicator();
}
},),],);
}
}
void insertIngredient() {
Future<bool> success = db.insertIngredient("banana2"));
success.then((success) {
if (success) {
setState(() {
futureIng = db.getIngredients();
});
});
}
void deleteIngredient() {
var future = db.deleteIngredient("banana2");
future.then((value) {
futureIng = db.getIngredients();
futureIng.then((value) {
setState(() {
print("asd");
});
});
});
}
按下getButton()
会调用insertIngredient()
,然后按下getDeleteButton()
会调用deleteIngredient()
。
因此,首先我插入“ banana2”成分,然后按Delete键将其删除。如您在deleteIngredient()
函数中所见,该项目已被删除,然后我更新了以后的版本并调用setState()
来重建输出文本。但是,FutureBuilder
现在被调用了2次,一次什么也没发生(香蕉2仍在输出),然后立即再次被删除。
这是怎么回事?
解决方法
我认为它是这样的: 首次将futurebuilder重建为其值已更改的窗口小部件,因此setState()方法使其进行重建。 第二次,是因为FutureBuilder重建了自己,因为您从AsyncSnapshot futureIng获得了值,并且这是您期望的“正常”重建。
因此,您不希望拥有的构建是由以下事实引起的:FutureIng的实例已更改,并且窗口小部件FutureBuilder像普通窗口小部件那样进行重建。
,我仍然不确定100%为什么要运行两次,但是第一次“不正确”运行,connectionstate正在等待,第二次“正确”运行是“完成”。所以我用一个简单的if语句解决了我的问题。