Flutter解析JSON时可空列表赋值与Widget返回类型错误排查
问题分析与修正方案
你代码里的问题分为3类,对应报错和隐藏的逻辑、语法错误:
1. 第一个报错的修复
Flutter空安全机制下,AsyncSnapshot.data为可空类型,即使你判断了snapshot.hasData,也需要手动添加非空断言确认值不为空,修改赋值逻辑:
List<SensorData> posts = snapshot.data!;
2. 第二个报错的修复
FutureBuilder的builder闭包要求必须返回Widget,snapshot.error是Object类型,需要用组件包裹后返回:
return Text('Error: ${snapshot.error.toString()}');
3. 隐藏的核心错误(JSON解析逻辑错误)
你返回的JSON结构本身是数组,且传感器数据存放在每个数组元素的data子字段中,原有解析逻辑完全不匹配,需要修改两处:
- 修正
SensorData.fromJson的语法错误,同时修改解析调用逻辑 - 修正
fetchSensorDatas的解析逻辑
4. 细节错误修复
- Text组件不能直接传入double类型,需要转成字符串
- ListView放在Column中需要设置
shrinkWrap: true避免布局溢出
修正后的完整代码
import 'dart:convert'; import 'package:flutter/material.dart'; import 'package:http/http.dart' as http; import 'package:flutter/foundation.dart'; class SensorData with ChangeNotifier { final String? timestamp; final double? temperature; final double? pressure; final double? humidity; SensorData({ @required this.timestamp, @required this.temperature, @required this.pressure, @required this.humidity, }); factory SensorData.fromJson(Map<String, dynamic> json) { return SensorData( timestamp: json['timestamp'] as String, temperature: json['temperature'] as double, pressure: json['pressure'] as double, humidity: json['humidity'] as double, ); } } class App extends StatefulWidget { @override _AppState createState() => _AppState(); } class _AppState extends State<App> { Future<List<SensorData>> fetchSensorDatas() async { // 替换为你的实际API地址 final http.Response response = await http.get(Uri.http(<my_API_url>)); final List responseJson = json.decode(response.body); return responseJson .map((item) => SensorData.fromJson(item['data'])) .toList(); } @override Widget build(BuildContext context) { return Scaffold( body: Container( child: Column( children: [ Container(height: 200), Expanded( child: FutureBuilder<List<SensorData>>( future: fetchSensorDatas(), builder: (context, snapshot) { if (snapshot.hasData) { List<SensorData> posts = snapshot.data!; return ListView( shrinkWrap: true, children: posts .map((post) => Text(post.temperature.toString())) .toList(), ); } else if (snapshot.hasError) { return Center( child: Text('加载失败: ${snapshot.error.toString()}'), ); } return const Center( child: CircularProgressIndicator(), ); }, ), ), ], ), ), ); } }
内容的提问来源于stack exchange,提问作者Cyril Bvt
相关产品推荐
相关产品推荐

