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

Flutter报错Null不是String子类型 汇率API数据解析问题求解

问题根因

你遇到的type 'Null' is not a subtype of type 'String'错误,是因为你声明Album类的msg字段为不可空的String类型,但解析JSON时直接从根节点取json['msg']返回了null,Dart无法完成类型转换触发报错。
https://api.exchangerate.host/latest接口返回的msg字段不是根级字段,而是嵌套在motd对象下,同时你要的汇率数据在根级的rates字段中,接口返回结构示例如下:

{
  "motd": {
    "msg": "If you or your company use this project or like what we doing, please consider backing us so we can continue maintaining and evolving this project.",
    "url": "..."
  },
  "base": "EUR",
  "date": "2024-xx-xx",
  "rates": {
    "AED": 3.6725,
    "AFN": 91.80,
    // 其余货币汇率
  }
}
修复方案

1. 修正Album类的解析逻辑

调整字段取值路径,同时新增rates字段存储汇率数据,可选增加空安全处理避免接口结构变化时再次崩溃:

class Album {
  final String msg;
  final Map<String, dynamic> rates;

  Album({
    required this.msg,
    required this.rates,
  });

  factory Album.fromJson(Map<String, dynamic> json) {
    return Album(
      // 从motd对象下取msg,空值时返回默认提示
      msg: json['motd']?['msg'] ?? '暂无提示信息',
      // 取根节点下的rates字段,空值时返回空Map
      rates: json['rates'] ?? <String, dynamic>{},
    );
  }
}

2. 调整页面展示逻辑

修改FutureBuilder的布局,同时展示提示信息和汇率列表:

@override
Widget build(BuildContext context) {
  return MaterialApp(
    title: 'Fetch Data Example',
    theme: ThemeData(
      primarySwatch: Colors.blue,
    ),
    home: Scaffold(
      appBar: AppBar(
        title: const Text('Fetch Data Example'),
      ),
      body: Center(
        child: FutureBuilder<Album>(
          future: futureAlbum,
          builder: (context, snapshot) {
            if (snapshot.hasData) {
              return Column(
                children: [
                  // 展示接口提示信息
                  Padding(
                    padding: const EdgeInsets.all(16.0),
                    child: Text(snapshot.data!.msg),
                  ),
                  // 展示货币汇率列表
                  Expanded(
                    child: ListView.builder(
                      itemCount: snapshot.data!.rates.length,
                      itemBuilder: (context, index) {
                        String currencyCode = snapshot.data!.rates.keys.elementAt(index);
                        num exchangeRate = snapshot.data!.rates.values.elementAt(index);
                        return ListTile(
                          title: Text('$currencyCode: $exchangeRate'),
                        );
                      },
                    )
                  )
                ],
              );
            } else if (snapshot.hasError) {
              return Text('${snapshot.error}');
            }
            return const CircularProgressIndicator();
          },
        ),
      ),
    ),
  );
}

内容的提问来源于stack exchange,提问作者Lakshan Costa

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 09:48:03