Flutter/Dart触发The method 'where' was called on null列表过滤问题
问题原因
你触发空调用报错的核心原因是调用where方法的时机早于空判断:
- 在
Stopin页面中,你先执行了stops.where(...)过滤操作,之后才判断stops == null走加载态,当Provider还没返回数据、stops为null时,过滤操作就会触发空调用错误 - 同时
Stops页面也存在同样的逻辑问题,直接对Provider拿到的routes调用where,没有先做空判断
修复代码
1. Stops页面修复
class Stops extends StatelessWidget { int stId; int mrId; String stTitle; Stops({this.stId, this.stTitle, this.mrId,}); @override Widget build(BuildContext context) { // 先获取原始数据,先做空判断再执行过滤 List<Routes> rawRoutes = Provider.of<List<Routes>>(context); List<Routes> filteredRoutes = []; if (rawRoutes != null) { filteredRoutes = rawRoutes.where((element) => element.mrId == mrId).toList(); } return Scaffold( appBar: AppBar(), body: rawRoutes == null ? Center( child: CircularProgressIndicator(), ) : ListView.builder( itemCount: filteredRoutes.length, itemBuilder: (context, index) { return ListTile( title: Text(filteredRoutes[index].mrTitle), onTap: () { Navigator.push( context, MaterialPageRoute( builder: (context) => Stopin( stId: filteredRoutes[index].mrId, ))); }, ); })); } }
2. Stopin页面修复
class Stopin extends StatelessWidget { final int stId; const Stopin({Key key, this.stId}) : super(key: key); @override Widget build(BuildContext context) { // 先获取原始数据,先做空判断再执行过滤 List<Stop> stops = Provider.of<List<Stop>>(context); List<Stop> filtered = []; if (stops != null) { filtered = stops.where((element) => element.stId == stId).toList(); } return Scaffold( appBar: AppBar(), body: stops == null ? Center( child: CircularProgressIndicator(), ) : ListView.builder( itemCount: filtered.length, itemBuilder: (context, index) { return ListTile( title: Text(filtered[index].stTitle), ); })); } }
按标题过滤实现方法
可以给两个页面分别加搜索输入框,拿到输入的关键词后修改过滤逻辑即可,实现步骤如下:
- 将页面改为StatefulWidget,用来存储输入的搜索关键词
- 过滤时叠加标题匹配规则即可,示例过滤代码:
// searchKeyword为输入框获取的搜索值,空字符串时默认不限制标题 if (rawRoutes != null) { filteredRoutes = rawRoutes.where((element) { bool idMatch = element.mrId == mrId; // 标题匹配规则:忽略大小写,包含关键词即为匹配 bool titleMatch = searchKeyword.isEmpty ? true : element.mrTitle.toLowerCase().contains(searchKeyword.toLowerCase()); return idMatch && titleMatch; }).toList(); }
stops列表的标题过滤逻辑和上面一致,把对应字段替换为stTitle即可。
内容的提问来源于stack exchange,提问作者user16357470
相关产品推荐
相关产品推荐

