我正在使用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);
});
}
});
}
答案 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/