Flutter(Dart)中提取并展示JSON指定值报错求解
问题分析与修复方案
核心错误原因
你遇到的type 'String' is not a subtype of 'int' of 'index'错误,根源是对返回的JSON结构理解错误:
- 接口返回的是直接的数组(
[]包裹),而非包含einzelwerte键的对象。你代码里的dataDecoded['einzelwerte']试图用字符串索引访问数组,这在Dart里不允许——数组只能用整数索引(比如[0])。
其他代码问题
除核心错误外,还有几个基础问题需要修正:
- 类型拼写错误:Dart基础类型为小写的
int、bool,不是大写的Int、Bool。 - val字段类型不统一:JSON里的
val可能是整数(湿度)、浮点数(温度)、字符串(天气状况),不能固定为int,需用dynamic适配。 - 数据模型与返回结构不匹配:接口返回多个Wetter对象的列表,但
fetchWetter试图返回单个Wetter对象,逻辑矛盾。 - 重复解析JSON:
jsonDecode(response.body)被调用两次,解析一次即可。
完整修复代码
1. 修正数据模型
class EinzelwerteList { final List<Wetter> einzelwerte; EinzelwerteList({ required this.einzelwerte, }); factory EinzelwerteList.fromJson(List<dynamic> parsedJson) { List<Wetter> einzelwerte = parsedJson.map((i) => Wetter.fromJson(i)).toList(); return EinzelwerteList(einzelwerte: einzelwerte); } } class Wetter { final String id; final dynamic val; // 用dynamic适配多种类型的val final int ts; final bool ack; Wetter({ required this.id, required this.val, required this.ts, required this.ack, }); factory Wetter.fromJson(Map<String, dynamic> json) { return Wetter( id: json['id'].toString(), val: json['val'], ts: json['ts'] as int, // 明确类型转换 ack: json['ack'] as bool, ); } }
2. 修正网络请求函数
Future<EinzelwerteList> fetchWetter() async { final response = await http.get(Uri.parse( 'http://192.168.178.37:8087/getBulk/hmip.0.homes.18c6789e-30e6-46c3-ba4b-1f94d284c178.weather.humidity,hmip.0.homes.18c6789e-30e6-46c3-ba4b-1f94d284c178.weather.temperature,hmip.0.homes.18c6789e-30e6-46c3-ba4b-1f94d284c178.weather.weatherCondition,hmip.0.homes.18c6789e-30e6-46c3-ba4b-1f94d284c178.weather.weatherDayTime,hmip.0.homes.18c6789e-30e6-46c3-ba4b-1f94d284c178.weather.windDirection,hmip.0.homes.18c6789e-30e6-46c3-ba4b-1f94d284c178.weather.windSpeed')); if (response.statusCode == 200) { final dataDecoded = jsonDecode(response.body) as List<dynamic>; // 提取湿度示例 final humidityItem = dataDecoded.firstWhere((item) => item['id'].contains('humidity')); debugPrint('湿度:${humidityItem['val']}'); return EinzelwerteList.fromJson(dataDecoded); } else { throw Exception('Failed to load Wetter'); } }
3. 修正UI部分(FutureBuilder)
void main() => runApp(const MyApp()); class MyApp extends StatefulWidget { const MyApp({super.key}); @override State<MyApp> createState() => _MyAppState(); } class _MyAppState extends State<MyApp> { late Future<EinzelwerteList> futureWetterList; @override void initState() { super.initState(); futureWetterList = fetchWetter(); } @override Widget build(BuildContext context) { return MaterialApp( title: 'Fetch Data Example', theme: ThemeData(primarySwatch: Colors.green), home: Scaffold( appBar: AppBar(title: const Text('Micha lernt Flutter & Dart')), body: Center( child: FutureBuilder<EinzelwerteList>( future: futureWetterList, builder: (context, snapshot) { if (snapshot.hasData) { // 提取并显示湿度值 final humidity = snapshot.data!.einzelwerte.firstWhere((w) => w.id.contains('humidity')).val; return Text('当前湿度:$humidity%'); } else if (snapshot.hasError) { return Text('${snapshot.error}'); } // 加载中显示圆形进度条 return const CircularProgressIndicator(); }, ), ), ), ); } }
关键修复点总结
- 直接解析返回的数组,不再尝试访问不存在的
einzelwerte键 - 修正Dart基础类型的大小写错误
- 用
dynamic处理多类型的val字段 - 让网络请求返回列表模型,匹配接口返回结构
- 用
firstWhere根据id精准提取需要的气象数据(比如湿度)
内容的提问来源于stack exchange,提问作者Mickro2010
相关产品推荐
相关产品推荐

