如何在Flutter中实现DropdownButton2的可复用化
改造思路
把原代码中硬编码的数据源、字段名、选中状态、提示文本全部抽象为参数,让组件仅通过传入对应参数就能适配ISD、国家、州三种场景。
通用组件代码
import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:dropdown_button2/dropdown_button2.dart'; class ReusableDropdown extends StatelessWidget { // 数据源列表(州/国家/ISD码列表) final List<Map<String, dynamic>> options; // 下拉项显示的字段名(如"stateName"/"countryName"/"isdCode") final String displayField; // 响应式选中值(Obx监听的Rx变量) final RxString selectedValue; // 下拉框提示文本 final String hintText; // 可选:下拉项的value字段(若与displayField不同,比如用ID作为value) final String? valueField; const ReusableDropdown({ super.key, required this.options, required this.displayField, required this.selectedValue, required this.hintText, this.valueField, }); @override Widget build(BuildContext context) { return Obx( () => DropdownButton2<String>( items: options.map((option) { final String itemValue = valueField != null ? option[valueField!].toString() : option[displayField].toString(); return DropdownMenuItem<String>( value: itemValue, child: Text(option[displayField].toString()), ); }).toList(), hint: Text(hintText), onChanged: (String? newValue) { if (newValue != null) selectedValue.value = newValue; }, value: options.any((element) { final String optionValue = valueField != null ? element[valueField!].toString() : element[displayField].toString(); return optionValue == selectedValue.value; }) ? selectedValue.value : options.isNotEmpty ? null : null, ), ); } }
三种场景使用示例
1. 州选择场景
// 假设countryController包含states列表和selectedState响应式变量 ReusableDropdown( options: countryController.states, displayField: "stateName", selectedValue: countryController.selectedState, hintText: 'Select State', )
2. 国家选择场景
// 假设countryController包含countries列表和selectedCountry响应式变量 ReusableDropdown( options: countryController.countries, displayField: "countryName", selectedValue: countryController.selectedCountry, hintText: 'Select Country', // 若需用国家ID作为选中值而非名称,传入valueField valueField: "countryId", )
3. ISD码选择场景
// 假设isdController包含isdCodes列表(结构如[{"isdCode": "+1", "country": "USA"}])和selectedIsd响应式变量 ReusableDropdown( options: isdController.isdCodes, displayField: "isdCode", selectedValue: isdController.selectedIsd, hintText: 'Select ISD Code', )
核心特性
- 完全基于Obx响应式,数据源或选中值变化时自动更新UI
- 支持自定义value字段,适配不同业务逻辑需求
- 保留原代码的校验逻辑:确保选中值存在于数据源中,否则自动置为null
内容的提问来源于stack exchange,提问作者Hanok Macha
相关产品推荐
相关产品推荐

