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

Flutter中动态TextFormField的控制器绑定与文本获取问题

修复动态TextFormField的控制器传递与增删问题

你的代码核心问题出在控制器列表未声明、删除逻辑的索引错误,以及没有正确绑定每个输入框的删除操作到对应的索引上。我帮你调整了代码,解决这些问题的同时保证能正确获取每个输入框的值:

class MyPets extends StatefulWidget {
  @override
  _MyPetsState createState() => _MyPetsState();
}

class _MyPetsState extends State<MyPets> {
  List<Widget> _children = [];
  // 首先要声明控制器列表,之前你的代码里漏了这一步!
  List<TextEditingController> controllers = [];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text("我的宠物"),
        actions: <Widget>[
          IconButton(icon: const Icon(Icons.add), onPressed: _addTextField)
        ],
      ),
      body: ListView(children: _children),
    );
  }

  void _addTextField() {
    final controller = TextEditingController();
    setState(() {
      // 添加控制器到列表
      controllers.add(controller);
      // 添加带删除按钮的输入框,绑定当前的索引
      _children.add(
        Row(
          children: [
            Expanded(
              child: TextFormField(
                controller: controller,
                decoration: InputDecoration(
                  hintText: "宠物名称 ${controllers.length}",
                ),
              ),
            ),
            IconButton(
              icon: const Icon(Icons.remove_circle),
              // 这里绑定当前的索引(添加时的列表长度-1),删除时用这个索引
              onPressed: () => _removeTextField(controllers.length - 1),
            ),
          ],
        ),
      );
    });
  }

  void _removeTextField(int index) {
    setState(() {
      // 先dispose对应的控制器,避免内存泄漏
      controllers[index].dispose();
      // 根据索引移除控制器和输入框
      controllers.removeAt(index);
      _children.removeAt(index);
    });
  }

  // 如果你需要获取所有输入框的值,可以调用这个方法
  void _getAllInputValues() {
    for (var controller in controllers) {
      print("输入框内容:${controller.text}");
    }
  }

  @override
  void dispose() {
    // 逐个dispose控制器,而不是只clear,防止内存泄漏
    for (var controller in controllers) {
      controller.dispose();
    }
    controllers.clear();
    super.dispose();
  }
}

关键改进点说明:

  • 声明控制器列表:添加了List<TextEditingController> controllers = [];,这是你之前代码里缺失的核心部分
  • 绑定删除索引:每个删除按钮都绑定了当前输入框对应的索引,删除时直接操作这个索引,避免了用_count导致的越界问题
  • 内存泄漏防护:删除输入框时先dispose对应的控制器,dispose生命周期里也逐个处理控制器,避免内存泄漏
  • 简化逻辑:去掉了没必要的_count变量,直接用控制器列表的长度来标记输入框的序号,更直观

如果需要获取所有输入框的值,直接调用_getAllInputValues方法即可,它会遍历所有控制器并打印文本内容。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.07 10:47:36