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
相关产品推荐
相关产品推荐

