Flutter API请求解析报错:Map<String,dynamic>无法转为List<dynamic>
问题解决:Map<String, dynamic> 无法转换为 List
错误原因
你的代码默认API返回照片对象数组(List(jsonDecode(responseBody) as List)这一步强制类型转换时触发错误。
修正步骤及代码
1. 修改数据请求与解析逻辑
将返回类型从List<Photo>改为单个Photo,调整解析逻辑适配单对象返回:
import 'dart:convert'; import 'package:http/http.dart' as http; Future<Photo> fetchPhotos(http.Client client) async { final response = await client.get( Uri.parse('Endpoint(hidden)'), ); return parsePhoto(response.body); } Photo parsePhoto(String responseBody) { final parsed = jsonDecode(responseBody) as Map<String, dynamic>; return Photo.fromJson(parsed); } class Photo { final bool canLogin; final bool canRegister; final List<dynamic> activities; const Photo({ required this.canLogin, required this.canRegister, required this.activities, }); factory Photo.fromJson(Map<String, dynamic> json) { return Photo( canLogin: json['canLogin'] as bool, canRegister: json['canRegister'] as bool, activities: json['activities'] as List<dynamic>, ); } }
2. 调整UI部分适配单对象数据
修改FutureBuilder类型,同时调整页面展示逻辑(单个对象无需GridView):
import 'package:flutter/material.dart'; import 'package:flutter/foundation.dart'; class Test extends StatefulWidget { const Test({super.key, required this.title}); final String title; @override State<Test> createState() => _TestState(); } class _TestState extends State<Test> { late Future<Photo> getData; @override void initState() { getData = fetchPhotos(http.Client()); super.initState(); } @override void dispose() { super.dispose(); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text('data'), backgroundColor: Colors.blue, ), floatingActionButton: TextButton( onPressed: () { setState(() { getData = fetchPhotos(http.Client()); }); }, child: const Text('Reload')), body: FutureBuilder<Photo>( future: getData, builder: (context, snapshot) { if (snapshot.hasData) { devtools.log('has data'); return PhotoDetail(photo: snapshot.data!); } else if (snapshot.hasError) { devtools.log('has error'); return Text(snapshot.error.toString()); } return const CircularProgressIndicator(); }, ), ); } } class PhotoDetail extends StatelessWidget { const PhotoDetail({super.key, required this.photo}); final Photo photo; @override Widget build(BuildContext context) { return Padding( padding: const EdgeInsets.all(16.0), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text('可登录: ${photo.canLogin}'), Text('可注册: ${photo.canRegister}'), const SizedBox(height: 16), const Text('活动列表:'), ...photo.activities.map((activity) => Text('- $activity')).toList(), ], ), ); } }
额外说明
- 如果API确实应该返回数组,需检查后端接口是否正确返回
[]包裹的数组格式; - 原代码
dispose方法中重新赋值getData属于无用操作,已移除; - 刷新按钮逻辑修改为重新发起请求,确保点击后获取最新数据。
内容的提问来源于stack exchange,提问作者Abdlrhman Bashir
相关产品推荐
相关产品推荐

