如何修复Flutter中‘_InternalLinkedHashMap’不是Iterable子类型错误?
问题解决:
type '_InternalLinkedHashMap<String, dynamic>' is not a subtype of type 'Iterable<dynamic>' 问题根源
你的代码期望API返回数组格式的JSON(如[{"title":"...",...},...]),但实际API返回的是单个对象或包含数组的嵌套对象,导致jsonDecode(response.body)得到的是Map而非Iterable,触发类型转换错误。
解决方案
步骤1:确认API返回结构
先查看调试控制台打印的response.body,判断返回格式:
- 格式A(嵌套数组):
{"data": [{"title":"...", "desc":"...", ...}, ...]} - 格式B(单个对象):
{"title":"...", "desc":"...", ...}
步骤2:修改仓库代码(Repo)
根据API返回格式二选一:
针对格式A(嵌套数组)
import 'dart:convert'; import 'package:http/http.dart' as http; import 'package:medreminder/TipsAndTricks/models/tips_model.dart'; class Repo{ final _baseUrl = 'http://10.0.2.2:8000/tips'; // 指定返回类型为List<Tips>,避免类型警告 Future<List<Tips>> getData() async{ try { final response = await http.get(Uri.parse(_baseUrl)); if(response.statusCode == 200){ print(response.body); // 先解析为Map,再取出数组部分(key需和API返回的字段名一致,比如是tips就写tips) Map<String, dynamic> responseMap = jsonDecode(response.body); Iterable it = responseMap['data']; List<Tips> tips = it.map((e) => Tips.fromJson(e)).toList(); return tips; } else { // 处理非200状态码,返回空列表 return []; } } catch (e) { print(e.toString()); // 捕获异常时返回空列表,避免后续UI报错 return []; } } }
针对格式B(单个对象)
import 'dart:convert'; import 'package:http/http.dart' as http; import 'package:medreminder/TipsAndTricks/models/tips_model.dart'; class Repo{ final _baseUrl = 'http://10.0.2.2:8000/tips'; Future<List<Tips>> getData() async{ try { final response = await http.get(Uri.parse(_baseUrl)); if(response.statusCode == 200){ print(response.body); // 解析为单个对象,再包装成列表返回 Map<String, dynamic> jsonData = jsonDecode(response.body); Tips tip = Tips.fromJson(jsonData); return [tip]; } else { return []; } } catch (e) { print(e.toString()); return []; } } }
步骤3:修复首页UI更新问题
异步获取数据后需要调用setState刷新UI,同时添加加载状态:
import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:medreminder/TipsAndTricks/models/tips_model.dart'; import 'package:medreminder/TipsAndTricks/screens/tips_details.dart'; import 'package:medreminder/TipsAndTricks/tips_repo.dart'; class TipsList extends StatefulWidget { const TipsList({super.key}); @override State<TipsList> createState() => _TipsListState(); } class _TipsListState extends State<TipsList> { List<Tips> listTips = []; Repo repo = Repo(); getData() async { // 接收返回的列表数据,调用setState更新UI List<Tips> fetchedTips = await repo.getData(); setState(() { listTips = fetchedTips; }); } @override void initState() { getData(); super.initState(); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( backgroundColor: Get.isDarkMode?Colors.grey[600]:Colors.white, leading: IconButton( onPressed: ()=>Get.back(), icon: Icon(Icons.arrow_back_ios, color: Get.isDarkMode?Colors.white:Colors.grey ), ), title: Text("Healthy Tips & Tricks", style: TextStyle( color: Get.isDarkMode?Colors.white:Colors.black ),), ), // 列表为空时显示加载指示器,否则渲染列表 body: listTips.isEmpty ? const Center(child: CircularProgressIndicator()) : ListView.builder( itemCount: listTips.length, itemBuilder: (context, index){ Tips tips = listTips[index]; return Card( child: ListTile( title: Text(tips.title), subtitle: Text(tips.source), leading: Image.network(tips.imageUrl), trailing: const Icon(Icons.arrow_forward_ios), onTap: (){ Navigator.push(context, MaterialPageRoute(builder: (context) => TipsDetails(tips))); }, ), ); }) ); } }
额外优化建议
- 给
Image.network添加错误占位符,避免图片加载失败导致UI崩溃:
leading: Image.network( tips.imageUrl, errorBuilder: (context, error, stackTrace) { return const Icon(Icons.broken_image); }, ),
- 可以使用
FutureBuilder替代手动管理状态,简化代码逻辑。
内容的提问来源于stack exchange,提问作者NyK
相关产品推荐
相关产品推荐

