修改Riverpod Notifier状态后UI未更新问题排查
修复SearchAnchor自动补全列表为空的问题
核心问题1:Google Places API返回字段映射错误
新版Google Places Autocomplete API的返回结果中,自动补全建议数组的字段是predictions,但你的AutocompleteResponse模型将其映射为suggestions,导致解析后数据始终为空。
修改Freezed模型:
@freezed class AutocompleteResponse with _$AutocompleteResponse { const factory AutocompleteResponse( // 用JsonKey将API的predictions字段映射到模型的suggestions参数 @SuggestionConverter() @JsonKey(name: "predictions") List<Suggestion> suggestions, ) = AutocompleteResponseData; factory AutocompleteResponse.fromJson(Map<String, dynamic> json) => _$AutocompleteResponseFromJson(json); }
核心问题2:suggestionsBuilder返回的Iterable未转换为List
suggestions.map(...)返回的是惰性Iterable,SearchAnchor无法正确渲染,需要显式转换为List。
修改SearchAnchor的suggestionsBuilder:
suggestionsBuilder: (context, controller) { if (!controller.isOpen) controller.openView(); return suggestionsState.when( data: (suggestions) => suggestions.map((suggestion) { return ListTile( title: Text(suggestion.structuredFormat.mainText.text), onTap: () {}, ); }).toList(), // 新增toList()转换为可渲染的列表 error: (_, __) => [const Text('加载出错')], loading: () => [const Text('加载中...')], ); },
优化点:避免重复触发搜索请求
你同时使用了SearchController的listener和SearchBar的onChanged,易导致重复调用接口,建议合并逻辑:
修改MapSearchBar的状态类:
class _MapSearchBarState extends ConsumerState<MapSearchBar> { final _searchController = SearchController(); @override void dispose() { _searchController.dispose(); // 记得释放控制器 super.dispose(); } @override Widget build(BuildContext context) { final suggestionsState = ref.watch(queryServiceProvider); return SearchAnchor( searchController: _searchController, viewBackgroundColor: kWhite, viewSurfaceTintColor: kWhite, dividerColor: kGrey, builder: (context, controller) => SearchBar( controller: controller, onChanged: (value) { controller.openView(); // 直接在onChanged中调用搜索,移除initState里的listener ref.read(queryServiceProvider.notifier).searchForQuery(value); }, ), suggestionsBuilder: (context, controller) { return suggestionsState.when( data: (suggestions) => suggestions.map((suggestion) { return ListTile( title: Text(suggestion.structuredFormat.mainText.text), onTap: () { controller.closeView(); // 补充选择后的逻辑 }, ); }).toList(), error: (_, __) => [const Text('加载出错')], loading: () => [const Text('加载中...')], ); }, ); } }
额外验证:确认API返回数据正常
在QueryService的searchForQuery中添加日志,验证解析后的建议列表非空:
final autocompleteResponse = AutocompleteResponse.fromJson(jsonDecode(response.body)); print("获取到的建议数量:${autocompleteResponse.suggestions.length}"); // 确认数量>0 state = AsyncData(autocompleteResponse.suggestions);
内容的提问来源于stack exchange,提问作者Edvard
相关产品推荐
相关产品推荐

