Flutter类型不匹配错误:_Map<String,dynamic>无法转为List<Map<String,dynamic>>
问题根源
错误提示type '_Map<String, dynamic>' is not a subtype of type 'List<Map<String, dynamic>>',本质是类型不匹配:
- 你定义的
_data是列表类型(List<Map<String, dynamic>>) - 但
futurecontroller.fetchData()实际返回的是单个映射类型(Map<String, dynamic>) - 直接把Map赋值给List,触发类型转换异常
从你打印的alldata内容也能看出来,它是类似{RAW: {BTC: {INR: {...}}}}的单层级结构,不是数组。
解决方案
根据你的展示需求,分两种场景处理:
场景1:仅展示单个币种数据
如果API只返回单条币种信息,直接把返回的Map包装成List即可:
Future<void> fetchalldata() async { final alldata = await futurecontroller.fetchData(); print('I am ${alldata}'); setState(() { _data = [alldata]; // 把单个Map塞进List里 print('This is${_data}'); }); }
这种情况下,ListView只会显示一行,原Text组件的取值逻辑out['RAW']['BTC']['INR']['FROMSYMBOL']可以保留。
场景2:展示所有币种数据
如果API返回的Map里包含多个币种(比如RAW下有BTC、ETH等多个键值对),需要把这些币种数据提取成List:
- 先修改数据解析逻辑:
Future<void> fetchalldata() async { final alldata = await futurecontroller.fetchData(); print('I am ${alldata}'); setState(() { // 安全提取RAW下的所有币种数据,转成List final rawMap = alldata?['RAW'] as? Map<String, dynamic> ?? {}; _data = rawMap.values.whereType<Map<String, dynamic>>().toList(); print('This is${_data}'); }); }
- 再调整Text组件的取值路径(现在List的每个元素是单个币种的INR数据):
return Text( out['INR']['FROMSYMBOL'].toString(), style: const TextStyle( color: Colors.green, ), );
完整修改代码(场景2示例)
import 'package:crypto_app/Services/api_service.dart'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; class HomePage extends StatefulWidget { const HomePage({super.key}); @override State<HomePage> createState() => _HomePageState(); } class _HomePageState extends State<HomePage> { ApiService futurecontroller = Get.put(ApiService()); List<Map<String, dynamic>> _data = []; Future<void> fetchalldata() async { final alldata = await futurecontroller.fetchData(); print('I am ${alldata}'); setState(() { final rawMap = alldata?['RAW'] as? Map<String, dynamic> ?? {}; _data = rawMap.values.whereType<Map<String, dynamic>>().toList(); print('This is${_data}'); }); } @override void initState() { super.initState(); fetchalldata(); } @override Widget build(BuildContext context) { return Scaffold( body: Obx( () => futurecontroller.isLoading.value ? const Center( child: CircularProgressIndicator( color: Colors.green, ), ) : ListView.builder( itemCount: _data.length, itemBuilder: (context, index) { final out = _data[index]; return Text( out['INR']['FROMSYMBOL'].toString(), style: const TextStyle( color: Colors.green, ), ); }, ), ), ); } }
内容的提问来源于stack exchange,提问作者Android Developer ATS
相关产品推荐
相关产品推荐

