生成建议时,flutter showSearch异步操作

时间:2019-12-11 20:59:48

标签: 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。

还有其他建议吗?

最终更新:

最后它确实起作用了。我的未来不返回数据,因为我不确定我的查询实际上是数据类型String。下面的代码是最终的运行版本。 (再次感谢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);
               });
         }
       });
 } 

1 个答案:

答案 0 :(得分:2)

返回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/