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

如何为动态数量的TextFormField创建带唯一名称的TextEditingController

解决方案

首先得把StatelessWidget改成StatefulWidget,因为需要管理控制器的生命周期,避免内存泄漏。动态数量的玩家控制器用列表存储是最合理的,不用纠结单独命名成firstPlayerController这种,列表索引就能对应每个玩家(比如controllers[0]就是第一个玩家的控制器,和命名效果一致)。

修改后的完整代码如下:

class PlayersIntroductionScreen extends StatefulWidget {
  const PlayersIntroductionScreen({Key? key, required this.playersNumber}) : super(key: key);

  final int playersNumber;

  @override
  State<PlayersIntroductionScreen> createState() => _PlayersIntroductionScreenState();
}

class _PlayersIntroductionScreenState extends State<PlayersIntroductionScreen> {
  // 用列表存储所有玩家的控制器
  late List<TextEditingController> _playerControllers;

  @override
  void initState() {
    super.initState();
    // 根据玩家数量初始化控制器列表
    _playerControllers = List.generate(
      widget.playersNumber,
      (index) => TextEditingController(),
    );
  }

  @override
  void dispose() {
    // 销毁所有控制器,防止内存泄漏
    for (var controller in _playerControllers) {
      controller.dispose();
    }
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('输入玩家名称')),
      body: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Column(
          children: [
            // 动态生成对应数量的TextFormField
            for (int i = 0; i < widget.playersNumber; i++)
              Padding(
                padding: const EdgeInsets.only(bottom: 12.0),
                child: TextFormField(
                  controller: _playerControllers[i],
                  decoration: InputDecoration(
                    labelText: '玩家${i + 1}名称',
                    border: const OutlineInputBorder(),
                  ),
                ),
              ),
            // 可以加个按钮获取所有玩家名称
            ElevatedButton(
              onPressed: () {
                List<String> playerNames = _playerControllers
                    .map((controller) => controller.text.trim())
                    .toList();
                // 这里可以处理玩家名称,比如传递到下一个页面
                print(playerNames);
              },
              child: const Text('确认'),
            )
          ],
        ),
      ),
    );
  }
}

关键说明:

  • initState里初始化控制器:只会在组件创建时执行一次,避免每次build都重建控制器导致输入内容丢失。
  • dispose里销毁所有控制器:这是必须的,防止Flutter内存泄漏。
  • 用List.generate快速创建对应数量的控制器,比手动写for循环更简洁。
  • 如果非要类似firstPlayerController的命名方式,其实可以通过列表索引来模拟,比如_playerControllers[0]就是第一个玩家的控制器,完全满足需求,而且动态数量下这种方式是唯一可行的。

内容的提问来源于stack exchange,提问作者Osama El Emam

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 03:42:14