You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Flutter中实现DropdownButton2的可复用化

可复用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 14:18:31