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

Flutter报错:FloatingActionButton内onPressed存在重复键,请求解

Flutter IMC计算器:解决“onPressed内部重复键”报错问题

报错原因

你遇到的“Duplicate keys”错误和FloatingActionButton的onPressed无关,真正问题出在表单字段的Key重复:

  • 你创建的_formKey(GlobalKey)本应绑定给Form组件,但错误地将其赋值给了三个TextFormField的key参数
  • GlobalKey在整个Widget树中必须唯一,重复使用同一个key会触发Flutter的重复键检测报错

另外代码存在逻辑漏洞:提交时判断的person.isValidPerson永远不会生效,因为打开对话框时仅重置了person属性,并未用输入框的值更新它。

修复步骤

1. 正确绑定Form的GlobalKey

把_formKey从所有TextFormField上移除,绑定到Form组件的key参数:

content: Form(
  key: _formKey, // 移到此处
  child: Column(
    mainAxisSize: MainAxisSize.min,
    children: [
      TextFormField(
        // 移除key: _formKey
        controller: _nameController,
        decoration: const InputDecoration(
          labelText: 'Nome',
        ),
        validator: (value) {
          if (value == null || value.isEmpty) {
            return 'Por favor, insira um nome';
          }
          return null;
        },
      ),
      TextFormField(
        // 移除key: _formKey
        controller: _heightController,
        decoration: const InputDecoration(
          labelText: 'Altura (cm)',
        ),
        keyboardType: TextInputType.number,
        inputFormatters: [
          FilteringTextInputFormatter.digitsOnly,
        ],
        validator: (value) {
          if (value == null || value.isEmpty) {
            return 'Por favor, insira uma altura';
          }
          return null;
        },
      ),
      TextFormField(
        // 移除key: _formKey
        controller: _weightController,
        decoration: const InputDecoration(
          labelText: 'Peso (kg)',
        ),
        keyboardType: TextInputType.number,
        inputFormatters: [
          FilteringTextInputFormatter.digitsOnly,
        ],
        validator: (value) {
          if (value == null || value.isEmpty) {
            return 'Por favor, insira um peso';
          }
          return null;
        },
      ),
    ],
  ),
),

2. 给TextFormField设置独立唯一Key(可选但推荐)

若需给每个TextFormField设置key,确保每个key唯一,比如使用ValueKey:

TextFormField(
  key: const ValueKey('name_field'),
  // 其他属性不变
),
TextFormField(
  key: const ValueKey('height_field'),
  // 其他属性不变
),
TextFormField(
  key: const ValueKey('weight_field'),
  // 其他属性不变
),

3. 修正提交逻辑的无效判断

移除person.isValidPerson判断(或先同步person属性再判断),当前代码中person属性未与输入框同步:

ElevatedButton(
  onPressed: () async {
    if (_formKey.currentState!.validate()) {
      await crud.addPerson(Person(
          personName: _nameController.text,
          personHeight: double.parse(_heightController.text),
          personWeight: double.parse(_weightController.text),
          personBMI: imcCalculator
              .returnIMCPerson(
                  double.parse(_heightController.text),
                  double.parse(_weightController.text))
              .bmi
              .toDouble()));
      setState(() {
        getPeople();
      });
      Navigator.of(context).pop();
    } else {
      ScaffoldMessenger.of(context).showSnackBar(
        const SnackBar(
          content: Text("Preencha todos os campos"),
        ),
      );
    }
    setState(() {
      getPeople();
    });
  },
  child: const Icon(Icons.send_rounded),
),

额外优化建议

  • 打开对话框时清空输入框控制器:在showDialog前添加_nameController.clear()、_heightController.clear()、_weightController.clear(),避免残留上次输入内容
  • 处理数值转换异常:使用double.tryParse替代double.parse,并添加空值判断,防止非数字输入引发报错

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 13:36:00