Flutter开发设置表单时TextFormField的onSaved回调出现String?类型赋值错误
错误原因
该报错由Dart空安全校验触发:TextFormField的onSaved回调传入的参数val是可空类型String?,而int.parse()方法要求传入非空的String类型参数,类型不匹配导致编译失败。
修复方案
1. 补充第一个输入框的校验逻辑
你已经给第二个心率输入框加了必填校验,给第一个代谢率输入框也补充相同的校验规则,确保只有输入内容不为空时才会执行onSaved回调,此时val必然为非空值。
2. 修改onSaved回调的空安全处理
在校验保证输入不为空的前提下,给val加上非空断言即可,也可以根据业务需求加默认值做兜底。
3. 调整提交按钮的执行顺序
原代码先执行save()再执行validate(),逻辑顺序错误,应该先校验通过再执行保存操作。
完整修改后的代码片段
class _MetabolixSettingsState extends State<MetabolixSettings> { int _metabolicRate = 0; // 补充第二个输入字段的存储变量 int _fatmaxHeartRate = 0; final _formKey = GlobalKey<FormState>(); @override Widget build(BuildContext context) { return Form( key: _formKey, child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: <Widget>[ Padding( padding: EdgeInsets.symmetric(horizontal: 8, vertical: 16), child: TextFormField( // 补充校验规则 validator: (value) { if (value == null || value.isEmpty) { return '请输入代谢率'; } return null; }, // 加非空断言处理空安全 onSaved: (val) => _metabolicRate = int.parse(val!), decoration: InputDecoration( border: OutlineInputBorder(), hintText: 'Enter your metabolic rate.', ), keyboardType: TextInputType.number, inputFormatters: <TextInputFormatter>[ FilteringTextInputFormatter.digitsOnly ], ), ), Padding( padding: EdgeInsets.symmetric(horizontal: 8, vertical: 16), child: TextFormField( // 补充onSaved回调 onSaved: (val) => _fatmaxHeartRate = int.parse(val!), decoration: InputDecoration( border: OutlineInputBorder(), hintText: 'Enter your FATMAX heart rate.', ), keyboardType: TextInputType.number, inputFormatters: <TextInputFormatter>[ FilteringTextInputFormatter.digitsOnly ], validator: (value) { if (value == null || value.isEmpty) { return '请输入FATMAX心率'; } return null; }, ), ), ElevatedButton( onPressed: () { // 先校验 再保存 if (_formKey.currentState!.validate()) { _formKey.currentState!.save(); ScaffoldMessenger.of(context) .showSnackBar(SnackBar(content: Text('Saving Settings'))); ScaffoldMessenger.of(context).hideCurrentSnackBar(); } FocusScopeNode currentFocus = FocusScope.of(context); currentFocus.unfocus(); }, child: Text('Save'), ), ], )); } }
兜底方案(可选)
如果不想依赖校验逻辑,希望无论输入是否为空都不报错,可以用默认值兜底的写法:
onSaved: (val) => _metabolicRate = int.parse(val ?? '0'),
如果val为空,会默认解析0赋值给变量。
内容的提问来源于stack exchange,提问作者Daniel Harper
相关产品推荐
相关产品推荐

