Flutter开发:如何将API数据加载到Dropdown组件?求助
问题:Flutter Dropdown组件无法加载API返回的数据
问题描述
本地字符串列表能正常加载到Dropdown组件,但调用API获取数据时,Dropdown无任何内容显示,结果为空。
API请求代码
Future<List<Agama>> getAgama() async { String url = Constant.baseURL; String token = await UtilSharedPreferences.getToken(); final response = await http.get( Uri.parse( '$url/auth/mhs_siakad/dosen', ), headers: { 'Authorization': 'Bearer $token', }, ); print(response.statusCode); print(response.body); if (response.statusCode == 200) { final result = json.decode(response.body)['nm_agama'] as Map<String, dynamic>; UserBiodata agama = UserBiodata.fromJson(result); List<Agama> l = agama.data ?? []; return l; } else { throw Exception(); } }
Widget代码
List<Agama>? religion = []; @override void initState() { super.initState(); BiodataProvider().getAgama(); } var dropdownAgama; ... FutureBuilder( future: BiodataProvider().getBiodata(), builder: (context, snapshot) { if (snapshot.hasData) { print(' ini Agama $religion'); return Column( children: [ Text( snapshot.data!.data!.name.toString(), style: bold5, ), DropdownButton( hint: const Text('Religion'), items: religion!.map((item) { return DropdownMenuItem( value: item.nmAgama.toString(), child: Text(item.idAgama.toString()), ); }).toList(), onChanged: (newVal) { setState(() { dropdownAgama = newVal; }); }, value: dropdownAgama, ), ], ); } else { return const Text('No Data'); } }), ...
数据模型代码
class Agama { String? id; String? idAgama; String? nmAgama; String? createdAt; String? updatedAt; dynamic createdBy; dynamic updatedBy; Agama( {this.id, this.idAgama, this.nmAgama, this.createdAt, this.updatedAt, this.createdBy, this.updatedBy}); Agama.fromJson(Map<String, dynamic> json) { id = json['id']; idAgama = json['id_agama']; nmAgama = json['nm_agama']; createdAt = json['created_at']; updatedAt = json['updated_at']; createdBy = json['created_by']; updatedBy = json['updated_by']; } Map<String, dynamic> toJson() { final Map<String, dynamic> data = <String, dynamic>{}; data['id'] = id; data['id_agama'] = idAgama; data['nm_agama'] = nmAgama; data['created_at'] = createdAt; data['updated_at'] = updatedAt; data['created_by'] = createdBy; data['updated_by'] = updatedBy; return data; } }
API返回数据截图

问题分析与修复方案
核心问题点
- API解析逻辑错误:从截图看,API返回的是包含
data数组的对象,但你代码里错误地取了nm_agama字段,且将其当作Map解析,完全不符合返回结构。 - 未更新UI状态:调用
getAgama()后,没有将返回结果赋值给religion列表,也没调用setState触发UI更新。 - FutureBuilder绑定错误:当前FutureBuilder关联的是
getBiodata(),与宗教数据加载无关,无法监听getAgama()的状态变化。
修复步骤
1. 修正API解析逻辑
修改getAgama方法,正确解析返回的数组数据:
Future<List<Agama>> getAgama() async { String url = Constant.baseURL; String token = await UtilSharedPreferences.getToken(); final response = await http.get( Uri.parse('$url/auth/mhs_siakad/dosen'), headers: {'Authorization': 'Bearer $token'}, ); print(response.statusCode); print(response.body); if (response.statusCode == 200) { // 直接提取data数组 final List<dynamic> resultList = json.decode(response.body)['data']; // 将数组元素逐个转为Agama对象 return resultList.map((item) => Agama.fromJson(item)).toList(); } else { throw Exception('加载宗教数据失败'); } }
2. 正确获取并更新数据
在Widget中新增加载方法,获取数据后更新状态:
List<Agama>? religion = []; @override void initState() { super.initState(); _loadReligionData(); } void _loadReligionData() async { try { List<Agama> data = await BiodataProvider().getAgama(); setState(() { religion = data; }); } catch (e) { print('加载失败:$e'); } }
3. 优化Dropdown的FutureBuilder(可选)
如果需要等待宗教数据加载完成再显示Dropdown,可单独为Dropdown绑定FutureBuilder:
// 替换原Dropdown代码 FutureBuilder<List<Agama>>( future: BiodataProvider().getAgama(), builder: (context, snapshot) { if (snapshot.hasData) { return DropdownButton( hint: const Text('选择宗教'), items: snapshot.data!.map((item) { return DropdownMenuItem( value: item.nmAgama, child: Text(item.nmAgama.toString()), // 建议显示宗教名称而非ID ); }).toList(), onChanged: (newVal) { setState(() { dropdownAgama = newVal; }); }, value: dropdownAgama, ); } else if (snapshot.hasError) { return Text('加载失败:${snapshot.error}'); } else { return const CircularProgressIndicator(); } }, ),
额外提示
- 检查
UserBiodata类是否多余,API返回结构不需要额外的包装类,可直接解析data数组。 - Dropdown的选项文本建议显示
nmAgama(宗教名称),而非idAgama,提升用户体验。
内容的提问来源于stack exchange,提问作者sharon
相关产品推荐
相关产品推荐

