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

Flutter DropdownButtonFormField复用异常:两个实例选中状态同步

问题原因

你的两个下拉框组件共用了同一个GeneralController实例的selectedState状态变量,因此选中其中一个时,另一个会同步更新状态值。

解决方案

方案1:将组件改为受控组件(推荐,组件更通用)

修改MyStatesDropdown1,让它接收外部传入的状态变量和更新回调,实现每个实例独立绑定不同状态:

import 'package:flutter/material.dart';
import 'package:get/get.dart';

class MyStatesDropdown1 extends StatelessWidget {
  final RxString selectedState;
  final Function(String?) onChanged;

  MyStatesDropdown1({
    super.key,
    required this.selectedState,
    required this.onChanged,
  });

  final istates = [
    {'scode': '35', 'sname': 'Andaman & Nicobar Islands'},
    {'scode': '37', 'sname': 'Andhra Pradesh'},
    {'scode': '12', 'sname': 'Arunachal Pradesh'},
    {'scode': '18', 'sname': 'Assam'},
    {'scode': '10', 'sname': 'Bihar'},
    {'scode': '04', 'sname': 'Chandigarh'},
    {'scode': '22', 'sname': 'Chattisgarh'},
    {'scode': '26', 'sname': 'Dadra & Nagar Haveli & Daman & Diu'},
    {'scode': '07', 'sname': 'Delhi'},
    {'scode': '30', 'sname': 'Goa'},
    {'scode': '24', 'sname': 'Gujarat'},
    {'scode': '06', 'sname': 'Haryana'},
    {'scode': '02', 'sname': 'Himachal Pradesh'},
    {'scode': '01', 'sname': 'Jammu & Kashmir'},
    {'scode': '20', 'sname': 'Jharkhand'},
    {'scode': '29', 'sname': 'Karnataka'},
    {'scode': '32', 'sname': 'Kerala'},
    {'scode': '38', 'sname': 'Ladakh'},
    {'scode': '31', 'sname': 'Lakshwadeep'},
    {'scode': '23', 'sname': 'Madhya Pradesh'},
    {'scode': '27', 'sname': 'Maharashtra'},
    {'scode': '14', 'sname': 'Manipur'},
    {'scode': '17', 'sname': 'Meghalaya'},
    {'scode': '15', 'sname': 'Mizoram'},
    {'scode': '13', 'sname': 'Nagaland'},
    {'scode': '21', 'sname': 'Odisha'},
    {'scode': '34', 'sname': 'Puducherry'},
    {'scode': '03', 'sname': 'Punjab'},
    {'scode': '08', 'sname': 'Rajasthan'},
    {'scode': '11', 'sname': 'Sikkim'},
    {'scode': '33', 'sname': 'Tamil Nadu'},
    {'scode': '36', 'sname': 'Telangana'},
    {'scode': '16', 'sname': 'Tripura'},
    {'scode': '09', 'sname': 'Uttar Pradesh'},
    {'scode': '15', 'sname': 'Uttrakhand'},
    {'scode': '19', 'sname': 'West Bengal'}
  ];

  @override
  Widget build(BuildContext context) {
    return Obx(() => Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Center(
              child: DropdownButtonFormField(
                decoration: InputDecoration(
                  isDense: true,
                  border: OutlineInputBorder(
                    borderRadius: BorderRadius.circular(5.0),
                  ),
                  focusedBorder: OutlineInputBorder(
                    borderRadius: BorderRadius.circular(5.0),
                  ),
                  hintText: 'Select State',
                  hintStyle: TextStyle(color: Colors.grey.shade800),
                ),
                value: selectedState.value == '' ? null : selectedState.value,
                onChanged: onChanged,
                items: istates.map((Map item) {
                  return DropdownMenuItem<String>(
                    value: item['scode'],
                    child: Text(item['sname']),
                  );
                }).toList(),
                icon: const Icon(Icons.arrow_drop_down),
                iconSize: 42,
              ),
            ),
          ],
        ));
  }
}

父页面使用方式

在包含标签页的页面中,定义两个独立的状态变量分别绑定到两个下拉框:

// 父页面中定义状态
final RxString billingSelectedState = ''.obs;
final RxString shippingSelectedState = ''.obs;

// 标签页内调用组件
TabBarView(
  children: [
    // 账单地址标签页
    MyStatesDropdown1(
      selectedState: billingSelectedState,
      onChanged: (newVal) {
        billingSelectedState.value = newVal ?? '';
        // 如需同步到全局控制器,可在此调用:
        // _generalController.updateBillingState(newVal ?? '');
      },
    ),
    // 收货地址标签页
    MyStatesDropdown1(
      selectedState: shippingSelectedState,
      onChanged: (newVal) {
        shippingSelectedState.value = newVal ?? '';
        // _generalController.updateShippingState(newVal ?? '');
      },
    ),
  ],
);

方案2:修改全局控制器,拆分独立状态

如果希望状态仍由GeneralController统一管理,可在控制器中添加两个独立的状态变量:

修改GeneralController

class GeneralController extends GetxController {
  // 拆分账单和收货地址的状态
  final RxString billingSelectedState = ''.obs;
  final RxString shippingSelectedState = ''.obs;

  void updateBillingState(String state) {
    billingSelectedState.value = state;
  }

  void updateShippingState(String state) {
    shippingSelectedState.value = state;
  }
}

修改下拉框组件

添加参数标记当前组件绑定的是账单还是收货地址:

class MyStatesDropdown1 extends StatelessWidget {
  final bool isBilling;
  final GeneralController _generalController = Get.find();

  MyStatesDropdown1({
    super.key,
    required this.isBilling,
  });

  // 状态列表省略,同方案1...

  @override
  Widget build(BuildContext context) {
    final selectedState = isBilling 
        ? _generalController.billingSelectedState 
        : _generalController.shippingSelectedState;

    final updateMethod = isBilling
        ? _generalController.updateBillingState
        : _generalController.updateShippingState;

    return Obx(() => Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Center(
              child: DropdownButtonFormField(
                decoration: InputDecoration(
                  isDense: true,
                  border: OutlineInputBorder(
                    borderRadius: BorderRadius.circular(5.0),
                  ),
                  focusedBorder: OutlineInputBorder(
                    borderRadius: BorderRadius.circular(5.0),
                  ),
                  hintText: 'Select State',
                  hintStyle: TextStyle(color: Colors.grey.shade800),
                ),
                value: selectedState.value == '' ? null : selectedState.value,
                onChanged: (newVal) {
                  if (newVal != null) {
                    updateMethod(newVal);
                  }
                },
                items: istates.map((Map item) {
                  return DropdownMenuItem<String>(
                    value: item['scode'],
                    child: Text(item['sname']),
                  );
                }).toList(),
                icon: const Icon(Icons.arrow_drop_down),
                iconSize: 42,
              ),
            ),
          ],
        ));
  }
}

父页面使用方式

// 账单地址标签页
MyStatesDropdown1(isBilling: true),

// 收货地址标签页
MyStatesDropdown1(isBilling: false),

内容的提问来源于stack exchange,提问作者gomesh munda

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 10:36:03