【问题标题】:Flutter Like button functionality using Futures使用 Futures 的 Flutter Like 按钮功能
【发布时间】:2018-08-07 06:26:58
【问题描述】:

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

到目前为止我所拥有的:

  • 提供Future<bool> 的存储库,用于确定图标应呈现的状态
  • FutureBuilder 调用存储库并将图标呈现为已保存/未保存。
  • Icon 包裹在 GestureDetector 中,当 onTap 被调用时,它会在 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: () {
                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;
}

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

【问题讨论】:

  • “isSaved”有什么作用?
  • @Yamin 我更新了帖子以包含isSaved 函数。

标签: dart flutter flutter-layout dart-async


【解决方案1】:

当您点击按钮时,将调用 setState。然后 FutureBuilder 将等待 isSaved 方法。如果保存方法正在进行中。 isSaved 会返回最后一个状态,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(() {

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

但是,如果方法耗时过长,则会出现延迟,从而导致糟糕的用户体验。在运行方法中最好将图标改为进度圈。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-10-13
    • 2023-03-22
    • 1970-01-01
    • 2018-08-11
    • 1970-01-01
    • 1970-01-01
    • 2022-10-21
    • 1970-01-01
    相关资源
    最近更新 更多