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

Flutter使用ListTile时勾选Checkbox如何同步TextField值到对应输入框

问题根因

你所有列表条目共用了全局的同一个charges和time文本编辑控制器,控制器内容变更会同步到所有绑定它的输入框,所以修改一个就会导致所有条目同步变化。

解决方案

给每个列表条目单独分配独立的文本编辑控制器,通过Map以book的id为key存储对应条目的控制器,修改时仅操作当前选中条目对应的控制器即可。

步骤1:替换全局控制器定义

删除原来全局的charges、time控制器,新增Map存储每个条目的独立控制器:

TextEditingController chargesMax = TextEditingController();
List _selectedCities = [];
// 以book.id为key,存储对应条目的控制器
Map<int, TextEditingController> chargesControllerMap = {};
Map<int, TextEditingController> timeControllerMap = {};

步骤2:修改选中逻辑,仅给当前条目控制器赋值

void _onCitySelected(bool selected, cityId) {
    if (selected == true) {
      setState(() {
        // 若当前条目无控制器则先初始化
        if (!chargesControllerMap.containsKey(cityId)) {
          chargesControllerMap[cityId] = TextEditingController();
          timeControllerMap[cityId] = TextEditingController();
        }
        // 仅给当前选中条目的charges输入框赋值
        chargesControllerMap[cityId]!.text = chargesMax.text;  
        _selectedCities.add(cityId);
      });
    } else {
      setState(() {
        _selectedCities.remove(cityId);
        // 可选:取消选中时释放对应控制器节约内存
        chargesControllerMap[cityId]?.dispose();
        timeControllerMap[cityId]?.dispose();
        chargesControllerMap.remove(cityId);
        timeControllerMap.remove(cityId);
      });
    }
  }

步骤3:修改列表条目组件,绑定对应独立控制器

修改buildCitesList方法中输入框绑定的控制器,不再使用全局控制器,改为读取当前book.id对应的独立控制器:

Widget buildCitesList(Book book) => ListTile(
        leading: checkboxCustom(context, _selectedCities.contains(book.id),
            (bool? selected) {
          if (selected != null) {
            setState(() {
              _onCitySelected(selected, book.id);
            });
          }
        }),
        title: Text(book.title, style: GoogleFonts.montserrat()),
        subtitle: Padding(
          padding: const EdgeInsets.only(top: 10),
          child: Row(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              // 确保当前条目控制器已初始化
              if (!chargesControllerMap.containsKey(book.id)) {
                chargesControllerMap[book.id] = TextEditingController();
              }
              if (!timeControllerMap.containsKey(book.id)) {
                timeControllerMap[book.id] = TextEditingController();
              },
              //charges输入框绑定当前条目对应控制器
              textformfieldCustomwithouticon1(
                  context,
                  TextInputType.number,
                  MediaQuery.of(context).size.width * 0.3,
                  chargesControllerMap[book.id]!,
                  (String value) {
                setState(() {
                  chargesControllerMap[book.id]!.text = value;
                  chargesControllerMap[book.id]!.selection = TextSelection.fromPosition(
                      TextPosition(offset: chargesControllerMap[book.id]!.text.length));
                });
              }, (value) {
                if (value == null || value.isEmpty) {
                  return '请输入内容';
                }
                return null;
              }, '费用', '费用', 10.0),
              SizedBox(
                width: 10,
              ),
              // time输入框绑定当前条目对应控制器
              textformfieldCustomwithouticon1(
                  context,
                  TextInputType.number,
                  MediaQuery.of(context).size.width * 0.3,
                  timeControllerMap[book.id]!,
                  (String value) {
                setState(() {
                  timeControllerMap[book.id]!.text = value;
                  timeControllerMap[book.id]!.selection = TextSelection.fromPosition(
                      TextPosition(offset: timeControllerMap[book.id]!.text.length));
                });
              }, (value) {
                if (value == null || value.isEmpty) {
                  return '请输入内容';
                }
                return null;
              }, '时间', '时间', 10.0),
            ],
          ),
        ),
      );

步骤4:页面销毁时释放所有控制器

重写页面的dispose方法,避免内存泄漏:

@override
void dispose() {
  chargesMax.dispose();
  // 释放所有条目控制器
  for (var controller in chargesControllerMap.values) {
    controller.dispose();
  }
  for (var controller in timeControllerMap.values) {
    controller.dispose();
  }
  super.dispose();
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 22:27:04