使用 Futures 的 Flutter Like 按钮功能

Flutter Like button functionality using Futures

我正在尝试构建一个保存按钮,让用户保存/取消保存(喜欢/不喜欢)ListView 中显示的项目。

我目前拥有的:

`

@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;
}

知道是什么原因造成的吗?

当您点击按钮时,将调用 setState。然后 FutureBuilder 将等待 isSaved 方法。如果保存方法正在进行中。 isSaved 将 return 最后的状态和 Icon 不会改变。

我建议等待Save和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(() {

                });
              },
            );
        }
      });
}

但是,如果这些方法花费的时间太长,则会延迟,从而导致糟糕的用户体验。最好在 运行 方法中将图标更改为进度圈。