Flutter开发附近地点应用报Null check operator used on a null value错误如何解决
问题根因
- 核心错误:你定义的
Query类中pages是Map<String, Page>类型(键为字符串类型的页面ID),不是数组类型,你直接用[0]/[1]这种数字索引访问Map,永远返回null,之后用!强制拆包就触发了空安全错误。 - 次要风险:就算你转成了数组,也可能出现当前位置附近10公里内的维基标注地点不足5个的情况,硬取下标
[4]也会出现索引越界的空错误。 - 模型隐藏风险:
Page类的coordinates、extract字段你没有做判空处理,接口返回这两个字段为空时也会触发解析错误。
修复步骤
第一步:调整数据解析逻辑,把Map转成按搜索权重排序的数组
维基返回的每个Page对象都带index字段,代表搜索结果的排序优先级,你可以在解析完数据后把Map转成有序List:
首先在HomeScreenState里新增一个存排序后页面的变量:
List<Page> sortedPages = [];
然后修改fecthlocationData方法里解析成功后的逻辑:
if (response.statusCode == 200) { locationSuggestion = await locationDataFinalFromJson(response.body); if (locationSuggestion != null) { // 把Map的value转成List,按index升序排序 sortedPages = locationSuggestion!.query.pages.values.toList() ..sort((a, b) => a.index.compareTo(b.index)); setState(() { isLoading = false; }); } else { print("null1"); } }
第二步:修改页面渲染逻辑,动态生成列表,避免硬取下标
把原来硬写5个MyBanner的部分改成用ListView.builder动态生成,有多少条数据渲染多少条:
body: isLoading ? Center( child: CircularProgressIndicator(), ) : sortedPages.isEmpty ? Center(child: Text("当前位置附近没有找到相关地点")) : ListView.builder( itemCount: sortedPages.length, itemBuilder: (context, index) { final page = sortedPages[index]; return MyBanner( locationName: page.title, imagePath: page.original.source, context: context, ); }, ),
第三步:补全模型类的判空逻辑,避免解析报错
修改Page.fromJson里的coordinates和extract字段的解析逻辑,加空处理:
factory Page.fromJson(Map<String, dynamic> json) => Page( pageid: json["pageid"], ns: json["ns"], title: json["title"], index: json["index"], // 新增coordinates判空 coordinates: json["coordinates"] == null ? [] : List<Coordinate>.from(json["coordinates"].map((x) => Coordinate.fromJson(x))), original: json["original"] == null ? Original( source: "https://tigres.com.tr/wp-content/uploads/2016/11/orionthemes-placeholder-image-1.png", width: 300, height: 200) : Original.fromJson(json["original"]), description: json["description"] == null ? "暂无描述" : json["description"], descriptionsource: json["descriptionsource"] == null ? " " : json["descriptionsource"], // 新增extract判空 extract: json["extract"] ?? "暂无详情", );
额外注意事项
- Dart中
!强制拆包前一定要100%确认值不为空,不确定的场景优先用?.访问+??设置默认值 - 不要硬编码列表长度,所有接口返回的列表都要做长度校验,优先用动态生成逻辑
- Map类型只能用对应的键类型访问,不能混用数字/字符串索引
内容的提问来源于stack exchange,提问作者Mehmet Karanlık
相关产品推荐
相关产品推荐

