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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.11 04:12:02