Flutter自定义DropdownButton如何同时返回选中项名称与转换值?
解决方案
要实现选中项同时获取name和conversion,核心是让下拉按钮返回整个数据对象,而不是单独的conversion字段。以下是两种实现方式:
方式一:直接使用Map传递(快速修改)
1. 修改自定义下拉按钮代码
把DropdownButton的泛型从String改为Map<String, dynamic>,同时调整参数和回调逻辑:
Widget customJsonDropDown( List<Map<String, dynamic>>? jsonList, Map<String, dynamic>? selectedItem, void Function(Map<String, dynamic>?) onChanged, ) { return Container( decoration: BoxDecoration( borderRadius: BorderRadius.circular(9), color: Colors.white, ), child: Padding( padding: const EdgeInsets.only(left: 10, right: 5), child: SizedBox( height: 50, child: DropdownButton<Map<String, dynamic>>( hint: const Text('Select unit'), value: selectedItem, onChanged: onChanged, items: jsonList?.map((item) { return DropdownMenuItem( value: item, // 传递整个对象 child: Text(item['name']), // 依然显示name字段内容 ); }).toList(), underline: Container(), isExpanded: true, ), ), ), ); }
2. 在父组件中获取完整数据
声明变量保存选中对象,通过回调直接提取name和conversion:
// 声明变量存储选中项 Map<String, dynamic>? _selectedUnit; // 调用自定义下拉按钮 customJsonDropDown( jsonData['Length'], // 传入Length对应的列表数据 _selectedUnit, (val) { setState(() { _selectedUnit = val; // 直接获取所需字段 String unitName = _selectedUnit!['name']; double conversionValue = _selectedUnit!['conversion']; // 后续业务逻辑处理 }); }, )
方式二:使用实体类(类型更安全)
如果项目规模较大,建议创建实体类避免Map键名拼写错误:
1. 创建Unit实体类
class Unit { final String name; final double conversion; final bool? baseUnit; Unit({ required this.name, required this.conversion, this.baseUnit, }); // 从Map转成实体类 factory Unit.fromJson(Map<String, dynamic> json) { return Unit( name: json['name'], conversion: json['conversion'], baseUnit: json['base_unit'], ); } }
2. 修改自定义下拉按钮代码
Widget customJsonDropDown( List<Unit>? unitList, Unit? selectedUnit, void Function(Unit?) onChanged, ) { return Container( decoration: BoxDecoration( borderRadius: BorderRadius.circular(9), color: Colors.white, ), child: Padding( padding: const EdgeInsets.only(left: 10, right: 5), child: SizedBox( height: 50, child: DropdownButton<Unit>( hint: const Text('Select unit'), value: selectedUnit, onChanged: onChanged, items: unitList?.map((unit) { return DropdownMenuItem( value: unit, child: Text(unit.name), ); }).toList(), underline: Container(), isExpanded: true, ), ), ), ); }
3. 转换JSON并使用下拉按钮
// 先将JSON列表转成Unit实体类列表 List<Unit> _lengthUnits = (jsonData['Length'] as List) .map((item) => Unit.fromJson(item)) .toList(); // 声明变量存储选中项 Unit? _selectedUnit; // 调用下拉按钮 customJsonDropDown( _lengthUnits, _selectedUnit, (val) { setState(() { _selectedUnit = val; // 类型安全地获取字段 String unitName = _selectedUnit!.name; double conversionValue = _selectedUnit!.conversion; }); }, )
内容的提问来源于stack exchange,提问作者Ahmad
相关产品推荐
相关产品推荐

