Flutter请求JSON报错List<dynamic>不是Map<String,dynamic>子类型如何解决
问题修复方案
报错根因
该错误是因为后端返回的JSON数据外层为数组结构(用[]包裹),json.decode(response.body)执行后得到的是List<dynamic>类型,但你当前的解析逻辑默认JSON外层为对象结构(用{}包裹),直接将列表类型传入需要Map<String, dynamic>参数的Txtscr.fromJson方法,触发了类型不匹配。
修复方案
方案1:适配数组返回(推荐,兼容多数据场景)
如果你的接口会返回多条Txtscr数据,按如下步骤修改:
- 调整
obtenirTxtscr方法的返回类型为List<Txtscr>,修改解析逻辑 - 同步修改UI层的变量声明、FutureBuilder泛型,适配列表渲染
方案2:兼容单条数据场景
如果确认接口只会返回1条数据,仅需要修改解析行代码即可,不需要调整其他逻辑:
// 原代码 return Txtscr.fromJson(json.decode(response.body)); // 修改为 return Txtscr.fromJson(json.decode(response.body)[0]);
适配多数据场景的完整代码
import 'dart:async'; import 'package:flutter/material.dart'; import 'package:http/http.dart' show get; import 'dart:convert'; void main() => runApp( MyApp( txtscr: obtenirTxtscr() ) ); class Txtscr { final String id; final String content; Txtscr({ required this.id, required this.content, }); factory Txtscr.fromJson(Map<String, dynamic> jsonData) { return Txtscr( id: jsonData['id'], content: jsonData['content'], ); } } // 修改返回类型为List<Txtscr> Future<List<Txtscr>> obtenirTxtscr() async { final jsonEndpoint = Uri.parse('https://www.domaine.com/txtscr.php'); final response = await get(jsonEndpoint); if(response.statusCode == 200) { // 解析为列表后批量转换 List<dynamic> jsonList = json.decode(response.body); return jsonList.map((item) => Txtscr.fromJson(item)).toList(); } else { throw Exception("Error al obtenir el JSON"); }} class MyApp extends StatelessWidget { // 修改变量类型为Future<List<Txtscr>> final Future<List<Txtscr>> txtscr; MyApp({Key? key, required this.txtscr}): super(key: key); @override Widget build(BuildContext context) { return MaterialApp( title: "JSON URL", theme: ThemeData( primarySwatch: Colors.red, ), home: Scaffold( appBar: AppBar( title: Text("Text Json"), ), body: Center( // 修改FutureBuilder泛型为List<Txtscr> child: FutureBuilder<List<Txtscr>>( future: txtscr, builder: (context, snapshot) { if(snapshot.hasData) { // 用列表渲染多条数据 return ListView.builder( itemCount: snapshot.data!.length, itemBuilder: (context, index) { final currentItem = snapshot.data![index]; return Padding( padding: const EdgeInsets.all(16.0), child: Text( "ID: ${currentItem.id}\nContent: ${currentItem.content}" ), ); }, ); } else if(snapshot.hasError) { return Text("${snapshot.error}"); } return CircularProgressIndicator(); }, ),),), ); } }
内容的提问来源于stack exchange,提问作者Marko
相关产品推荐
相关产品推荐

