Flutter报错:List<Series<Hakedis,dynamic>>不是List<Series<dynamic,num>>子类型
问题核心原因
- 类型不匹配:你给
LineChart配置了domainAxis: charts.NumericAxisSpec,该轴要求X轴的domain值必须是num类型,但你当前定义的Series第二个泛型参数为dynamic,且domainFn返回值为DateTime类型,和要求的泛型List<Series<dynamic, num>>完全不符。 - 数据解析错误:API返回的
tarih是月份字符串(如August),你在Hakedis.fromJson中直接将字符串赋值给DateTime类型的tarih字段,运行时必然会触发类型转换错误。
修复方案
步骤1:修正Hakedis类的字段定义和解析逻辑
你可以将月份字符串转为对应数字(1-12)适配数值轴要求,也可以保留DateTime类型搭配时间轴使用,以下是数值轴适配方案:
class Hakedis { Hakedis({ required this.id, required this.tarihMonth, required this.disadet, }); final int id; // 存储月份对应数字1-12,符合数值轴num类型要求 final int tarihMonth; final String disadet; // 月份字符串转数字映射表 static const _monthMap = { "January": 1, "February": 2, "March": 3, "April":4, "May":5, "June":6, "July":7, "August":8, "September":9, "October":10, "November":11, "December":12 }; factory Hakedis.fromJson(Map<String, dynamic> jsonData) => Hakedis( id: int.parse(jsonData['id'].toString()), // 把接口返回的月份字符串转成数字 tarihMonth: _monthMap[jsonData['tarih']] ?? 0, disadet: jsonData['disadet'].toString(), ); Map<String, dynamic> toJson() => { "id": id, "tarih": _monthMap.entries.firstWhere((e) => e.value == tarihMonth).key, "disadet": disadet, }; }
步骤2:修正ShowChart组件的泛型定义
明确Series的第二个泛型参数为int,匹配数值轴的类型要求:
class ShowChart extends StatelessWidget { final List<Hakedis> data; const ShowChart({super.key, required this.data}); // 泛型第二个参数改为int,符合num类型要求 static List<charts.Series<Hakedis, int>> _createSampleData(List<Hakedis> dataAPI) { return [ charts.Series<Hakedis, int>( id: 'dis adet', colorFn: (_, __) => charts.MaterialPalette.blue.shadeDefault, areaColorFn: (_, __) => charts.MaterialPalette.blue.shadeDefault.lighter, // X轴返回int类型的月份数字 domainFn: (Hakedis hakedis, _) => hakedis.tarihMonth, // Y轴返回数值 measureFn: (Hakedis hakedis, _) => double.tryParse(hakedis.disadet)?.round() ?? 0, data: dataAPI, ) ]; } @override Widget build(BuildContext context) { return Container( child: charts.LineChart( _createSampleData(data), defaultRenderer: charts.LineRendererConfig(includeArea: true, stacked: true), animate: true, domainAxis: charts.NumericAxisSpec( tickProviderSpec: charts.BasicNumericTickProviderSpec(zeroBound: false), // 可选:把X轴数值转回月份名称显示,更直观 tickFormatterSpec: charts.BasicNumericTickFormatterSpec((num? value) { const monthNames = ["","一月","二月","三月","四月","五月","六月","七月","八月","九月","十月","十一月","十二月"]; return monthNames[value?.toInt() ?? 0]; }), ), ), ); } }
步骤3:修正FutureBuilder的泛型声明
明确泛型避免隐式类型转换异常:
FutureBuilder<List<Hakedis>>( future: getChartData(widget), builder: (context, dataapi) { if (dataapi.hasError) print(dataapi.error); return dataapi.hasData ? ShowChart(data: dataapi.data!) : const Center(child: CircularProgressIndicator()); }, )
如果你想保留DateTime类型的X轴,只需要把
NumericAxisSpec替换为DateTimeAxisSpec,同时将Series第二个泛型参数改为DateTime,对应调整tarih字段的解析逻辑即可。
内容的提问来源于stack exchange,提问作者canarcho
相关产品推荐
相关产品推荐

