我正在尝试构建一个保存按钮,该按钮可让用户保存/取消保存ListView
中显示的项目。
到目前为止我所拥有的:
Future<bool>
的存储库,用于确定图标应在哪个状态呈现FutureBuilder
,调用存储库并将图标呈现为已保存/未保存。Icon
包裹在GestureDetector
中,当调用setState
时,它会在onTap
调用内调用存储库。`
@override
Widget build(BuildContext context) {
return FutureBuilder(
future: _repository.isSaved(item),
builder: (BuildContext context, AsyncSnapshot<bool> snapshot) {
switch (snapshot.connectionState) {
case ConnectionState.waiting:
case ConnectionState.none:
case ConnectionState.active:
return Icon(Icons.favorite_border);
case ConnectionState.done:
return GestureDetector(
child: Icon(
snapshot.data ? Icons.favorite : Icons.favorite_border,
color: snapshot.data ? Colors.red : null),
onTap: () {
setState(() {
if (snapshot.data) {
_repository.removeItem(item);
} else {
_repository.saveItem(item);
}
});
},
);
}
});
}
`
我遇到的问题是,当我点击以将项目保存在列表中时-该项目已保存但是直到我将其滚动到屏幕之外然后再次打开时,图标才更新。 当我点击以取消保存项目时,其状态会立即反映出来并按预期更新。
我怀疑保存调用比删除调用花费的时间更长。这两个都是async
操作:
void removeItem(String item) async {
_databaseClient.deleteItem(item);
}
void saveItem(String item) async {
_databaseClient.saveItem(item);
}
@override
void deleteItem(String item) async {
var client = await db;
client.delete("items_table", where: "item = '$item'"); // returns Future<int> but I'm not using this currently
}
void _saveItem(String item) async {
var client = await db;
client.insert("items_table", item); // returns Future<int> but I'm not using this currently
}
Future<bool> isSaved(String name) async {
var matching = await _databaseClient.getNameByName(name);
return matching != null && matching.isNotEmpty;
}
有什么想法会导致这种情况吗?
答案 0 :(得分:2)
点击按钮时,将调用setState。然后FutureBuilder将等待isSaved方法。如果保存方法正在进行中。 isSaved将返回上一个状态,图标不会更改。
我建议等待Save and Remove方法的结果,然后再调用setState。
@override
Widget build(BuildContext context) {
return FutureBuilder(
future: _repository.isSaved(item),
builder: (BuildContext context, AsyncSnapshot<bool> snapshot) {
switch (snapshot.connectionState) {
case ConnectionState.waiting:
case ConnectionState.none:
case ConnectionState.active:
return Icon(Icons.favorite_border);
case ConnectionState.done:
return GestureDetector(
child: Icon(
snapshot.data ? Icons.favorite : Icons.favorite_border,
color: snapshot.data ? Colors.red : null),
onTap: () async{
if (snapshot.data) {
await _repository.removeItem(item);
} else {
await _repository.saveItem(item);
}
setState(() {
});
},
);
}
});
}
但是,如果方法花费的时间太长,则会延迟,从而导致不良的用户体验。最好在运行方法期间将图标更改为进度圈。