为什么Flutter中buildSuggestions报字符串-int类型错误但buildResults运行正常
报错原因
- 变量未初始化及变量名不匹配:
buildResults方法中你定义了suggestionList变量,但当query为空时,仅对suggestion赋值,没有给suggestionList赋值,未初始化的列表变量调用时直接触发类型错误。同时两个方法的ListView的itemCount属性绑定的是suggestion.length,但实际渲染用的数据源是suggestionList,当两个列表长度不一致时,索引超出列表范围会触发类型错误。输入内容时能正常展示,是因为输入内容时query不为空,触发了suggestionList的赋值逻辑,且此时suggestion的长度刚好和suggestionList一致,暂时没有触发索引越界的问题。 - 语法错误:你代码里使用了中文单引号
‘’来取值,部分代码块中where方法缺少闭合右括号,编译时也会触发异常。 - 遍历参数取值错误:你
where方法遍历的是列表元素,如果你的列表元素实际是数组类型而非Map类型,用字符串'season'作为下标取值时,就会直接抛出string is not a subtype of int报错。
buildSuggestions不生效的原因
你当前buildSuggestions的title仅渲染了season字段的值,没有按照预期拼接sport字段,所以不会显示season: sport的格式。同时你不需要对返回的suggestionList做字段裁剪,只需要在渲染层控制展示的字段即可,保留完整数据不会影响选中后展示完整字段的需求。
修复后的代码示例
Widget buildResults(BuildContext context) { final List<dynamic> suggestionList; if (query.isEmpty) { // 统一给suggestionList赋值 suggestionList = search; } else { suggestionList = controls .where((item) => // 替换为英文单引号 item['season'].toLowerCase().contains(query)) .toList(); } return ListView.builder( itemBuilder: (context, index) => ListTile( onTap: () { close(context, 'a'); }, // 结果页展示完整信息,可自行扩展color、id等字段 title: Text("${suggestionList[index]['season']}: ${suggestionList[index]['sport']}"), subtitle: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text("颜色:${suggestionList[index]['color']}"), Text("ID:${suggestionList[index]['id']}"), ], ) ), // itemCount绑定正确的数据源长度 itemCount: suggestionList.length, ); } Widget buildSuggestions(BuildContext context) { final List<dynamic> suggestionList; if (query.isEmpty) { suggestionList = recentSearch; } else { suggestionList = controls .where((item) => item['season'].toLowerCase().contains(query)) .toList(); } return ListView.builder( itemBuilder: (context, index) => ListTile( onTap: () { // 点击时把当前选中的内容赋值给query,再触发结果展示 query = suggestionList[index]['season']; showResults(context); }, // 建议列表展示season: sport格式 title: Text("${suggestionList[index]['season']}: ${suggestionList[index]['sport']}"), ), // 绑定正确的长度 itemCount: suggestionList.length, ); }
额外注意点
- 确认你的
controls、search、recentSearch列表中的元素是Map类型,如果是数组类型,需要把下标改为对应的数字索引取值,比如item[0]代替item['season']的形式。 - 如果需要同时支持sport字段搜索,可以在where判断里添加
item['sport'].toLowerCase().contains(query)的逻辑,用||连接即可。
内容的提问来源于stack exchange,提问作者born.a.bot
相关产品推荐
相关产品推荐

