Flutter 如何将接口返回的JSON国家数据填充为DropdownMenuItem选项
问题核心原因梳理
你遇到的问题主要由3个不匹配导致:
- 数据模型和实际接口返回的外层字段不匹配:你定义的
GetCountry类读取外层isSuccess字段,但是实际接口返回的外层成功状态字段是status - 数据模型和实际接口返回的内层字段不匹配:你定义的
CountryModal类读取countryName、int类型id,但实际接口返回的名称字段是stateName、id是字符串类型 - 没有将接口拉取到的结果赋值给下拉菜单的数据源
_countrylist,导致下拉菜单的items始终为空
修复步骤
1. 修正数据模型,对齐实际接口返回
import 'dart:convert'; GetCountry getCountryFromJson(String str) => GetCountry.fromJson(json.decode(str)); String getCountryToJson(GetCountry data) => json.encode(data.toJson()); class GetCountry { GetCountry({ required this.data, this.exceptionInfo, this.message, this.messages, required this.isSuccess, }); List<CountryModal> data; dynamic exceptionInfo; dynamic message; dynamic messages; bool isSuccess; factory GetCountry.fromJson(Map<String, dynamic> json) => GetCountry( // 对齐实际接口的成功状态字段 isSuccess: json["status"] ?? false, data: List<CountryModal>.from(json["data"].map((x) => CountryModal.fromJson(x))), exceptionInfo: json["exceptionInfo"], message: json["message"], messages: json["messages"], ); Map<String, dynamic> toJson() => { "data": List<dynamic>.from(data.map((x) => x.toJson())), "exceptionInfo": exceptionInfo, "message": message, "messages": messages, "isSuccess": isSuccess, }; } class CountryModal { CountryModal({ required this.id, required this.countryName, }); // 对齐实际接口的id类型(字符串) String id; // 如果你实际调用的是获取国家的接口,这里保留countryName即可;如果是返回stateName的接口,就把字段名改成stateName String countryName; factory CountryModal.fromJson(Map<String, dynamic> json) => CountryModal( id: json["id"], // 对应上面的字段名调整读取的key countryName: json["countryName"] ?? json["stateName"] ?? "", ); Map<String, dynamic> toJson() => { "id": id, "countryName": countryName, }; }
2. 页面中调用接口赋值给下拉数据源
在你的StatefulWidget的initState生命周期中调用接口,拉取数据后赋值给_countrylist并刷新页面:
List<CountryModal> _countrylist = []; // 修改为可空类型,适配未选择的空状态 String? mycountry; @override void initState() { super.initState(); loadCountryData(); } Future<void> loadCountryData() async { // 替换为你实际的授权token String authToken = "你的接口授权token"; try { GetCountry res = await Getcountry(authToken); if(res.isSuccess){ setState(() { _countrylist = res.data; }); } } catch (e) { print("国家数据加载失败:$e"); } }
3. 修正下拉菜单代码,适配空安全
DropdownButton<String>( // 明确指定value的类型为String,避免类型不匹配报错 items: _countrylist.map((item) { return DropdownMenuItem<String>( child: Text( item.countryName, style: const TextStyle(fontSize: 14.0), ), // 现在id已经是字符串类型,不需要再调用toString value: item.id, ); }).toList(), hint: const Text( "Please select the country", style: TextStyle( color: Colors.black45, ),), onChanged: (newVal) { setState(() { mycountry = newVal; }); }, value: mycountry, )
内容的提问来源于stack exchange,提问作者palak
相关产品推荐
相关产品推荐

