You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 07:45:33