如何在DropDownField中通过setState设置JSON数据并仅展示name字段
解决方案
你当前的问题核心是DropDownField的items参数要求传入List<String>类型的选项列表,而你目前传入的是包含完整食物对象的Map数组,只需要提取所有元素的name字段生成字符串列表即可。
快速修复方案
直接修改DropDownField的配置即可,不需要改动原有数据解析逻辑:
DropDownField( onValueChanged: (dynamic value) { // 若需要同步获取选中食物的id,可通过名称匹配查找 final matchedFood = food.firstWhere((item) => item['name'] == value, orElse: () => null); if (matchedFood != null) { setState(() { food_id = matchedFood['id'].toString(); }); } }, value: food_id, // 如果你要展示的是选中的名称,这里可以改为存储选中的name字段变量 required: false, labelText: 'Search food', // 核心修改:提取所有name字段生成选项列表 items: food.map((foodItem) => foodItem['name'].toString()).toList(), )
规范优化方案(推荐)
为了避免动态类型导致的字段拼写错误、类型不匹配问题,建议先定义食物数据模型再处理:
步骤1:定义Food模型类
class Food { final int id; final String name; final int calories; Food({ required this.id, required this.name, required this.calories, }); factory Food.fromJson(Map<String, dynamic> json) { return Food( id: json['id'] as int, name: json['name'] as String, calories: json['calories'] as int, ); } }
步骤2:修改State层逻辑
class _FoodWidgetState extends State<FoodWidget> { @override void initState() { fetchFood(); super.initState(); } // 改为存储选中的名称,也可单独存储选中的Food对象 String? selectedFoodName; List<Food> foodList = []; Future<void> fetchFood() async { final String response = await rootBundle.loadString('assets/list_food.json'); final data = json.decode(response); setState(() { // 解析为类型安全的Food对象数组 foodList = (data["food"] as List).map((item) => Food.fromJson(item)).toList(); }); } @override Widget build(BuildContext context) { return Container( padding: EdgeInsets.all(15.0), child: Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: <Widget>[ DropDownField( onValueChanged: (dynamic value) { setState(() { selectedFoodName = value as String; // 需要获取对应id/卡路里时直接调用即可 // int? selectedId = foodList.firstWhere((e) => e.name == value).id; }); }, value: selectedFoodName, required: false, labelText: 'Search food', items: foodList.map((food) => food.name).toList(), ), ]), ); } }
内容的提问来源于stack exchange,提问作者bubaebi
相关产品推荐
相关产品推荐

