Flutter解析JSON报错List<dynamic>不是List<String>子类型如何解决
错误原因
jsonDecode 解析JSON后,所有数组类型默认都会被推断为List<dynamic>,Dart不支持List<dynamic>到List<String>的隐式类型转换,所以无论是实体类赋值还是路由传参时直接传递videos字段,都会触发类型不匹配报错。
解决方案
方案一:全链路使用实体类(推荐,可维护性更高)
1. 修正JSON实体类的fromJson方法,显式转换videos的类型
factory VideoDetails.fromJson(Map<String, dynamic> json) { return VideoDetails( name: json['name'] as String, playList: json['playList'] as String, // 两种转换方式二选一即可 videos: List<String>.from(json["videos"]), // 或者用 videos: (json["videos"] as List).cast<String>(), ); }
2. 修正读取JSON的方法,把解析结果转换为实体类列表
Future<List<VideoDetails>> getPlayerList() async { String data = await DefaultAssetBundle.of(context).loadString("assets/lists/v-player.json"); final jsonResult = jsonDecode(data) as List; return jsonResult.map((item) => VideoDetails.fromJson(item)).toList(); }
3. 修正FutureBuilder代码,使用强类型的实体类
FutureBuilder<List<VideoDetails>>( future: getPlayerList(), builder: (BuildContext context, AsyncSnapshot<List<VideoDetails>> snapshot) { if (snapshot.connectionState == ConnectionState.waiting) { return const Center(child: Text("Loading...")); } if (snapshot.hasError) { return Center(child: Text("加载失败:${snapshot.error}")); } final list = snapshot.data!; return ListView.builder( itemCount: list.length, itemBuilder: (context, index) { var item = list[index]; return ListTile( leading: const FaIcon(FontAwesomeIcons.video), title: Text(item.name), trailing: Row( mainAxisSize: MainAxisSize.min, children: [ Text('${item.videos.length}'), const Icon(Icons.arrow_forward_ios_rounded), ], ), onTap: () { if(item.videos.isNotEmpty) { Navigator.pushNamed(context, '/player', arguments: VideoArguments( item.name, item.playList, item.videos, )); } else { //... } }, ); } ); } )
方案二:临时修复(仅解决当前传参报错)
如果不想修改整体解析逻辑,直接在路由传参的位置对videos做类型转换即可:
Navigator.pushNamed(context, '/player', arguments: VideoArguments( item['name'] as String, item['playList'] as String, List<String>.from(item['videos']), ));
额外注意事项
你提供的JSON示例中videos数组最后一个元素末尾多了一个逗号,属于JSON语法错误,解析时会报错,需要去掉:
"videos": [ "q2ZZlUsnX5Y", "ANpas6oyZjw", "5qwP-SOEdKg", "hWm62l-d3DE", "F07RJdvQ77w" // 移除末尾多余的逗号 ]
内容的提问来源于stack exchange,提问作者mafortis
相关产品推荐
相关产品推荐

