Flutter展示Swagger API数据时List<dynamic>非Map子类型错误如何解决
报错根本原因
你的API返回的是JSON数组(外层包裹[],内部是多个行程对象),但当前代码把整个数组传给了接收Map<String, dynamic>类型参数的Tour.fromJson方法,触发了类型不匹配报错。同时你原来的Tour.fromJson方法内部错误地使用json[0]['xxx']的写法,把Map类型参数当成数组取值,逻辑也存在错误。
分步修改方案
1. 修改 tour.dart 实体类的fromJson工厂方法
移除所有[0]索引,直接从当前Map参数中取值:
factory Tour.fromJson(Map<String, dynamic> json) { return Tour( lieferdatum: json['lieferdatum'], tourId: json['tourId'], tourBezeichnung: json['tourBezeichnung'], kundenAnzahl: json['kundenAnzahl'], menge: json['menge'], mandantId: json['mandantId'], mandant: json['mandant'], showOnMobile: json['showOnMobile'], fahrerId1: json['fahrerId1'], fahrerId2: json['fahrerId2'], fahrerId3: json['fahrerId3'], fahrer1: json['fahrer1'], fahrer2: json['fahrer2'], fahrer3: json['fahrer3'], ); }
2. 修改 touren.dart 的数据请求与状态定义
- 把Future返回值从单个Tour改成Tour列表
- 调整解析逻辑,遍历JSON数组转成Tour对象列表
- 修正日期选择后的刷新逻辑
// 状态定义从单Tour改成列表 Future<List<Tour>> futureTour; // 调整fetchTour返回值与解析逻辑 Future<List<Tour>> fetchTour() async { String username = '---'; String password = '---'; String basicAuth = 'Basic ' + base64Encode(utf8.encode('$username:$password')); final response = await http.get( Uri.parse(url + '---'), // 这里记得把_selectedDate拼到请求参数里,否则切换日期不生效 headers: {'authorization': basicAuth}); if (response.statusCode == 200) { List<dynamic> jsonList = jsonDecode(response.body); return jsonList.map((jsonItem) => Tour.fromJson(jsonItem)).toList(); } else { throw Exception('Failed to load Tour: ${response.statusCode}'); } } // 修改日期选择器逻辑,加判空、更新futureTour Future<DateTime> _showPicker(BuildContext context) { return showDatePicker( context: context, initialDate: DateTime.now(), firstDate: DateTime(1990), lastDate: DateTime(2100), ).then((pickedDate) { if(pickedDate != null) { _selectedDate = '${pickedDate.year}-${pickedDate.month}-${pickedDate.day}'; setState(() { futureTour = fetchTour(); // 重新赋值触发重新请求 }); } return null; }); }
3. 修改FutureBuilder渲染逻辑
把原来的单组件渲染改成遍历列表生成所有行程的GestureDetector,直接替换你写死的测试组件即可:
FutureBuilder<List<Tour>>( future: futureTour, builder: (context, snapshot) { if (snapshot.hasData) { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: snapshot.data.map((tour) { return GestureDetector( onTap: () { // 可直接拿到当前点击的tour对象做业务逻辑 Navigator.pop(context); }, child: MyTwoLineText(tour.tourId, tour.kundenAnzahl), ); }).toList(), ); } else if (snapshot.hasError) { return Text("${snapshot.error}"); } return CircularProgressIndicator(); }, ), // 原来写死的多个MyTwoLineText测试代码可以全部删除
内容的提问来源于stack exchange,提问作者moboldi
相关产品推荐
相关产品推荐

