Flutter获取JSON数据遇类型不匹配异常,UI无法加载数据求助
Flutter JSON解析与FutureBuilder数据展示问题修复
核心错误分析
- getUsers方法错误抛出数据而非返回:在
RESTAPIService的getUsers方法中,响应状态码为200时使用throw抛出解析结果,导致Future始终处于异常状态,FutureBuilder永远无法进入snapShot.hasData分支,界面一直显示Loading。 - map方法传参格式错误:
getUsersList里的parsebody.map<User>({(json) => ...})误用大括号,实际创建了_CompactLinkedHashSet集合,而非传递JSON转Model的回调函数,这就是类型不匹配异常的根源。 - User类fromJson方法设计错误:当前
fromJson返回Map类型且仅修改实例属性,不符合JSON转Model的逻辑,无法正确生成User对象供UI使用。
修正后的代码
修正后的RESTAPIService类
class RESTAPIService{ String apiUrl = "https://mocki.io/v1/048e68cc-9ddb-4aca-8264-6e9f8f273fd2"; Future<List<User>> getUsers() async{ final response = await http.get(Uri.parse(apiUrl)); print(response.body); if(response.statusCode == 200){ return getUsersList(response.body); // 替换throw为return,正常返回数据 }else{ throw Exception("Couldn't fetch data"); } } List<User> getUsersList(String responseBody){ final parsebody = json.decode(responseBody).cast<Map<String, dynamic>>(); // 把大括号{}改为小括号(),传递正确的转换函数 return parsebody.map<User>((json) => User.fromJson(json)).toList(); } }
修正后的User模型类
class User{ String name; String city; String image; User({required this.name, required this.city, required this.image}); // 改用工厂构造函数,直接从JSON生成User对象 factory User.fromJson(Map<String, dynamic> json){ return User( name: json['name'], city: json['city'], image: json['image'], ); } Map<String, dynamic> toJson(){ final Map<String, dynamic> data = new Map<String, dynamic>(); data['name'] = this.name; data['city'] = this.city; data['image'] = this.image; return data; } }
优化后的FutureBuilder调用代码
child: FutureBuilder( future: apiService.getUsers(), builder: (context, snapShot){ // 新增异常状态处理,避免异常时一直显示Loading if(snapShot.hasError){ return Center(child: Text('加载失败: ${snapShot.error}')); } if(snapShot.hasData){ return ListView.builder( itemCount: snapShot.data!.length, itemBuilder: (context, index){ return InkWell( onTap: (){}, child: Container( decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(10), boxShadow: [ BoxShadow( blurRadius: 3, spreadRadius: 3, color: Colors.grey.withOpacity(0.3), ) ] ), margin: EdgeInsets.symmetric(vertical: 10, horizontal: 10), padding: EdgeInsets.symmetric(vertical: 10, horizontal: 10), child: ListTile( title: Text(snapShot.data![index].name ?? '', style: TextStyle( fontSize: 18, color: Colors.black, ),), subtitle: Text(snapShot.data![index].city ?? '', style: TextStyle( fontSize: 15, color: Colors.black, ),), leading: ClipOval( child: Image.network(snapShot.data![index].image, fit: BoxFit.cover, width: 60, height: 60,), ), ), ), ); } ); }else{ return Container( child: Center( child: Text("Loading...", style: TextStyle( color: Colors.black, fontSize: 15, )), ), ); } }, ),
内容的提问来源于stack exchange,提问作者Madushanka Premakuamara
相关产品推荐
相关产品推荐

