android - Flutter showSearch 构建建议时的异步操作

标签 android asynchronous flutter dart

我正在使用 flutter showSearch 函数来搜索地址。到目前为止一切正常。现在我想实现每次用户更改搜索输入时都会重建的建议。为此,我使用 flutter 地理编码库。

问题是我不知道在使用 buildSuggestions 函数构建建议时如何执行异步操作。

显然我不能简单地使 buildSuggestions 函数异步,但如果可以的话我的代码将如下所示:

@override
Future<Widget> buildSuggestions(BuildContext context) async {

  var addresses = await Geocoder.local.findAddressesFromQuery(query);

  final Iterable<Address> suggestions = query.isEmpty
      ? _history
      : addresses;

  return _SuggestionList(
    query: query,
    suggestions: suggestions.map<String>((String i) => '$i').toList(),
    onSelected: (String suggestion) {
      query = suggestion;
      this.close(context, query);
    },
  );
}

一定有办法实现我想做的事情。有什么建议吗?

更新:

在 Frank06 的帖子的帮助下,我编写了以下代码:


   @override
  Widget buildSuggestions(BuildContext context) {
    return FutureBuilder(
        future: Geocoder.local.findAddressesFromQuery(query),
        builder: (BuildContext context, AsyncSnapshot<List<Address>> snapshot) {
          // check if snapshot.hasData

          if (snapshot.connectionState == ConnectionState.done) {
            List<Address> addresses;
            if (snapshot.hasData) {
              addresses = snapshot.data;
            } else {
              addresses = List<Address>();
            }

            List<String> addressNames = addresses.map((address) {
              return address.addressLine;
            }).toList();

            final Iterable<String> suggestions =
                query.isEmpty ? _history : addressNames;

            return _SuggestionList(
              query: query,
              suggestions: suggestions.map<String>((String i) => '$i').toList(),
              onSelected: (String suggestion) {
                query = suggestion;
                this.close(context, query);
              },
            );
          } else {
            return _SuggestionList(
                query: query,
                suggestions: List<String>(),
                onSelected: (String suggestion) {
                  query = suggestion;
                  this.close(context, query);
                });
          }
        });
  }

我觉得我已经接近解决方案了,但目前我遇到了 snapshot.hasData 总是返回 false 的问题。

还有什么建议吗?

最终更新:

终于成功了。我的 future 不会返回数据,因为我不确定我的查询实际上是字符串数据类型。下面的代码是最终的功能版本。 (再次感谢 Frank06!)。

@override
 Widget buildSuggestions(BuildContext context) {
   String queryString = query;

   return FutureBuilder(
       future: queryString.length > 0 ? Geocoder.local.findAddressesFromQuery(queryString) : Future.value(List<Address>()),
       builder: (BuildContext context, AsyncSnapshot<List<Address>> snapshot) {

         if (snapshot.connectionState == ConnectionState.done) {
           List<Address> addresses;
           if (snapshot.hasData) {
             addresses = snapshot.data;
           } else {
             addresses = List<Address>();
           }

           List<String> addressNames = addresses.map((address) {
             return address.addressLine;
           }).toList();

           final Iterable<String> suggestions =
               query.isEmpty ? _history : addressNames;

           return _SuggestionList(
             query: query,
             suggestions: suggestions.map<String>((String i) => '$i').toList(),
             onSelected: (String suggestion) {
               query = suggestion;
               this.close(context, query);
             },
           );
         } else {
           return _SuggestionList(
               query: query,
               suggestions: List<String>(),
               onSelected: (String suggestion) {
                 query = suggestion;
                 this.close(context, query);
               });
         }
       });
 } 

最佳答案

返回一个FutureBuilder:

Future<Widget> buildSuggestions(BuildContext context) {
  return FutureBuilder(
    future: Geocoder.local.findAddressesFromQuery(query),
    builder: (BuildContext context, AsyncSnapshot snapshot) {
      // check if snapshot.hasData
      var addresses = snapshot.data;

      final Iterable<Address> suggestions = query.isEmpty
          ? _history
          : addresses;

      return _SuggestionList(
        query: query,
        suggestions: suggestions.map<String>((String i) => '$i').toList(),
        onSelected: (String suggestion) {
          query = suggestion;
          this.close(context, query);
        },
      );
   )
}

FutureBuilder 构建在 StatefulWidget 之上。尝试使用 StatefulWidget 解决这个问题并不是错误,只是级别较低且更加乏味。

这篇文章详细解释了:https://flutterigniter.com/build-widget-with-async-method-call/

关于android - Flutter showSearch 构建建议时的异步操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59293983/

相关文章:

java - 如何在安卓上隐藏公钥?

java - 如何处理公共(public)抽象 boolean 响应

android - 如何从主 UI 线程检测到 Parse 的 query.findInBackground 已完成并返回数据?

node.js - 无法理解 ASYNC npm 包中的 ASYNC 系列

Flutter - 堆叠在一张条形图中的水平条形图

控制台中未显示 flutter 异常

Android说重复输入,但事实并非如此

android - 在滚动期间检查项目是否位于 ListView 适配器中的第一个位置

c# - WebRequest.GetResponse() 在几次请求后超时

Flutter 使用异步数据填充表单