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

Flutter中TextField输入时Dropdown/Radio值重置问题求助

问题:键盘弹出时Dropdown/Radio值重置,TextField不受影响
  • 从API获取输入字段数据,选择Dropdown值后,点击TextField弹出键盘时Dropdown值重置;选择Radio按钮时,其他值也会重置。
  • 已尝试三种方案无效:1. GlobalKey包裹Dropdown;2. 单独封装ListView.builder为Widget;3. bool变量控制ListView.builder构建。
  • 排查发现:键盘弹出时CarAdOne内的ListView.builder重建,导致Dropdown等控件重新实例化,但TextField值未受影响。
核心问题与修复方案

核心原因

每次ListView.builder重建时,你都在重新生成selectedValueList(覆盖之前的用户选择),而TextField的输入是直接修改已存在的selectedValueList元素,所以没被重置。

修复步骤

  1. 把selectedValueList的初始化移到API数据加载完成后,而非itemBuilder中:
    不要在ListView.builder的itemBuilder里每次都重新生成selectedValueList,这会覆盖用户已选择的值。应该在getInputFields成功获取数据后,初始化一次selectedValueList。

  2. Dropdown/Radio控件绑定selectedValueList中的对应值,而非默认值:
    比如Dropdown的dropDownValue要从selectedValueList取,而不是固定用data.categoryFieldName;Radio的groupValue也要绑定到selectedValueList的对应值。

  3. 避免在itemBuilder中做状态初始化操作:
    itemBuilder会频繁调用(重建时),任何状态初始化都应该放在initState、didChangeDependencies或者Provider的方法里。


修改后的关键代码

1. 在Provider的getInputFields方法中初始化selectedValueList

// AdsInputField类中的getInputFields方法
Future<void> getInputFields({required String categoryId, required String pageId}) async {
  // ... 原有API请求逻辑 ...
  // 数据获取成功后初始化selectedValueList
  selectedValueList = adsInputFieldList.map((element) {
    if (element.categoryTypeId == '4') {
      if (element.attributes.isEmpty) {
        return AddSummaryModel(
          name: element.categoryFieldName,
          nameAr: element.categoryFieldNameArabic,
          value: [''],
          field: element.categoryTypeName,
        );
      } else {
        return AddSummaryModel(
          name: element.categoryFieldName,
          nameAr: element.categoryFieldNameArabic,
          value: List.generate(element.attributes.length, (index) => 'false'),
          field: element.categoryTypeName,
        );
      }
    } else {
      return AddSummaryModel(
        name: element.categoryFieldName,
        nameAr: element.categoryFieldNameArabic,
        value: [''],
        field: element.categoryTypeName,
      );
    }
  }).toList();
  notifyListeners(); // 通知状态更新
}

2. 修改ListView.builder中的Dropdown和Radio部分

// Dropdown部分(case "2")
case "2":
  var dropdownList = data.attributes
      .map((e) => e.attributeName)
      .toSet()
      .toList();
  dropdownList.insert(0, data.categoryFieldName);
  return Padding(
    padding: EdgeInsets.symmetric(vertical: 10.h),
    child: SelectOptionForAd(
      index: index,
      dropdownName: data.categoryFieldName,
      // 绑定selectedValueList中的值,而非默认值
      dropDownValue: value.selectedValueList[index].value[0] == '' 
          ? data.categoryFieldName 
          : value.selectedValueList[index].value[0],
      dropdownlist: dropdownList,
      // 确保选择后更新selectedValueList
      onChanged: (newValue) {
        value.selectedValueList[index].value[0] = newValue;
        value.notifyListeners();
      },
    ),
  );

// Radio部分(case "3")
case "3":
  return Padding(
    padding: EdgeInsets.symmetric(vertical: 10.h),
    child: Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        H2semi(text: data.categoryFieldName),
        for (int radioIndex = 0; radioIndex < data.attributes.length; radioIndex++)
          RadioListTile(
            title: H3semi(text: data.attributes[radioIndex].attributeName),
            value: radioIndex,
            // 绑定selectedValueList中的值
            groupValue: int.tryParse(value.selectedValueList[index].value[0]) ?? 0,
            onChanged: (newValue) {
              value.selectedValueList[index].value[0] = newValue.toString();
              value.notifyListeners();
            },
          ),
      ],
    ),
  );

3. 移除itemBuilder中生成selectedValueList的代码

删除ListView.builder的itemBuilder开头的这段代码:

value.selectedValueList =
value.adsInputFieldList.map((element) {
// ... 原有生成逻辑 ...
}).toList();

内容的提问来源于stack exchange,提问作者Numan Ahmad

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 23:25:35