Flutter TypeAheadField无法显示维基百科API搜索结果求助
问题解决:flutter_typeahead调用维基百科API不显示结果
问题分析与修复步骤
1. 修正API返回数据的提取
维基百科该接口返回的JSON结构外层是包含pages数组的对象,你直接返回了解码后的整个对象,而TypeAhead需要的是可迭代的结果列表,必须提取pages数组返回。
修改BackendService的getSuggestions方法:
static Future<Iterable<dynamic>> getSuggestions(query) async { var res = await CallApi().wikipediaGet('search/title?q=$query&limit=5'); var data = jsonDecode(res.body); // 返回pages数组,而非整个对象 return data['pages'] ?? []; }
2. 移动TextEditingController的声明位置
你在build方法内声明_controller,每次组件重建都会创建新的控制器,导致输入状态异常,应该将其声明为State类的成员变量:
class _YourSearchPageState extends State<YourSearchPage> { // 移到这里作为成员变量 final TextEditingController _controller = TextEditingController(); @override Widget build(BuildContext context) { // 原build内容,移除内部的_controller声明 return Scaffold(...); } }
3. 修正ItemBuilder的内容展示
API返回的每个suggestion是包含title等字段的Map对象,你之前直接转字符串会显示无效内容,需要提取具体字段展示:
itemBuilder: (context, suggestion) { return ListTile( leading: const Icon(Icons.book), title: Text(suggestion['title']), // 显示维基页面标题 ); },
4. 可选:添加错误排查逻辑
为了快速定位请求问题,建议在getSuggestions里添加错误捕获:
static Future<Iterable<dynamic>> getSuggestions(query) async { try { var res = await CallApi().wikipediaGet('search/title?q=$query&limit=5'); if (res.statusCode == 200) { var data = jsonDecode(res.body); return data['pages'] ?? []; } else { print('请求失败:${res.statusCode}'); return []; } } catch (e) { print('请求异常:$e'); return []; } }
完整修改后的代码示例
搜索页面代码
class YourSearchPage extends StatefulWidget { const YourSearchPage({super.key}); @override State<YourSearchPage> createState() => _YourSearchPageState(); } class _YourSearchPageState extends State<YourSearchPage> { final TextEditingController _controller = TextEditingController(); @override Widget build(BuildContext context) { return Scaffold( backgroundColor: Colors.grey[300], body: Padding( padding: const EdgeInsets.all(10.0), child: TypeAheadField( textFieldConfiguration: TextFieldConfiguration( controller: _controller, textInputAction: TextInputAction.search, autofocus: true, decoration: const InputDecoration( border: OutlineInputBorder() ) ), suggestionsCallback: (pattern) async { if (pattern != null && pattern.length > 0) { return await BackendService.getSuggestions(pattern); } else { return []; } }, itemBuilder: (context, suggestion) { return ListTile( leading: const Icon(Icons.book), title: Text(suggestion['title']), ); }, onSuggestionSelected: (suggestion) { Get.back(); }, ) ) ); } }
后端服务类代码
class BackendService { static Future<Iterable<dynamic>> getSuggestions(query) async { try { var res = await CallApi().wikipediaGet('search/title?q=$query&limit=5'); if (res.statusCode == 200) { var data = jsonDecode(res.body); return data['pages'] ?? []; } else { print('维基API请求失败,状态码:${res.statusCode}'); return []; } } catch (e) { print('维基API请求异常:$e'); return []; } } }
内容的提问来源于stack exchange,提问作者Anele
相关产品推荐
相关产品推荐

