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

Flutter实现点击按钮动态新增表单组件及跨页传值

动态新增输入组件+独立存值+跨页传值实现方案

你参考PHP计数循环的实现思路在Flutter中完全可行,只需要适配Flutter声明式UI的状态驱动规则即可,具体实现步骤如下:


1. 定义核心状态变量

不要直接写死单个输入组件,在页面State类中统一维护所有输入框的控制器,保证每个输入框内容独立管控,同时避免内存泄漏:

late List<TextEditingController> _inputControllers;
final _formKey = GlobalKey<FormState>(); // 你原有代码里的表单key可以保留

@override
void initState() {
  super.initState();
  // 初始化时默认创建1个控制器,对应页面初始展示1个输入模块
  _inputControllers = [TextEditingController()];
}

@override
void dispose() {
  // 页面销毁时统一释放所有控制器资源
  for (final controller in _inputControllers) {
    controller.dispose();
  }
  super.dispose();
}

2. 实现新增组件逻辑

给指定的新增按钮绑定点击事件,每次点击时新增一个控制器,通过setState触发页面重绘即可自动渲染新的输入组件:

void _addInputModule() {
  setState(() {
    _inputControllers.add(TextEditingController());
  });
}

3. 改造页面渲染逻辑

保留你原有代码中buildTitle()、buildDateTimePickers()等部分不变,仅把原来写死的buildWidget()替换为循环渲染逻辑,遍历控制器列表批量生成自定义输入组件:

@override
Widget build(BuildContext context) => Scaffold(
      appBar: AppBar(
        leading: const CloseButton(),
        actions: buildEditingActions(), // 原有操作栏逻辑保留,可以把提交跳转逻辑放在这里
        backgroundColor: Colors.red,
      ),
      body: SingleChildScrollView(
        padding: const EdgeInsets.all(12),
        child: Form(
          key: _formKey,
          child: Column(
            mainAxisSize: MainAxisSize.min,
            children: <Widget>[
              const Text("Text...",style: TextStyle(fontSize: 24)),
              buildTitle(),
              const SizedBox(height: 12),
              buildDateTimePickers(),
              const Text("\nText",style: TextStyle(fontSize: 24)),
              // 替换原来的buildWidget(),循环生成所有输入模块
              ..._inputControllers.asMap().entries.map((entry) {
                final index = entry.key;
                final controller = entry.value;
                return Padding(
                  padding: const EdgeInsets.only(bottom: 12),
                  // 替换为你自己开发的自定义输入Widget
                  child: YourCustomInputWidget(
                    label: "Text${index + 1}", // 按你需要的规则命名模块
                    controller: controller, // 绑定对应控制器,保证内容独立
                  ),
                );
              }).toList(),
              // 新增按钮放在列末尾
              ElevatedButton(
                onPressed: _addInputModule,
                child: const Text("新增输入模块"),
              )
            ],
          ),
        ),
      ),
    );

注意:你的自定义输入Widget需要把TextEditingController作为对外参数暴露,不要在自定义Widget内部初始化控制器,否则组件重建时会出现输入内容丢失、多输入框内容联动错乱的问题。

4. 跨页面传递所有输入内容

需要跳转展示页时,直接遍历控制器列表收集所有输入值,通过路由参数传递到目标页面即可:

void _navigateToDisplayPage() {
  // 先执行表单校验
  if (_formKey.currentState?.validate() != true) return;
  // 收集所有输入框的内容
  final List<String> allInputValues = _inputControllers.map((c) => c.text.trim()).toList();
  // 跳转时传值
  Navigator.push(
    context,
    MaterialPageRoute(
      builder: (context) => YourDisplayPage(contentList: allInputValues),
    ),
  );
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 10:24:13