Flutter:无法在第一次提交时获取文本字段值

Flutter: Unable to get textfield value on first submission

我有一个内页表单,其中包含四个不同的字段和一个按钮。

我有一个奇怪的问题,这是我正在做的事情:

  1. 填写表格
  2. 点击添加按钮//variables are null
  3. 如果我再次点击 添加 按钮,我的值就正确了

我想,也许是某些库或代码导致了问题,所以我减少了代码以缩小范围,现在我的代码非常简单,只有一个字段带有 material.dart 导入包。但问题仍然存在。 :(

注意到:点击添加按钮总是return以前状态的数据比当前状态的数据。

示例:

  1. 用值 1000
  2. 填写表格
  3. 点击添加按钮//prints null
  4. 将值更新为 2000
  5. 点击添加按钮//prints 1000
  6. 将值更新为 3000
  7. 点击添加按钮//prints 2000
  8. 等等....

这里是完整的代码:

import 'package:flutter/material.dart';

class AddFees extends StatefulWidget {
  @override
  State<StatefulWidget> createState() => new _AddFees();
}

class _AddFees extends State<AddFees> {
  final addFeesFormKey = new GlobalKey<FormState>();
  final addFeesScaffoldKey = new GlobalKey<ScaffoldState>();

  String _fees;

  TextFormField fees;

  RaisedButton addFee;

  @override
  void initState() {
    super.initState();
  }

  void _submit() {
    final form = addFeesFormKey.currentState;

    if (form.validate()) {
      setState(() {
        print(_fees);
        form.save();
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    fees = TextFormField(
      keyboardType: TextInputType.number,
      onSaved: (val) => _fees = val,
      decoration: InputDecoration(labelText: 'Fees'),
      validator: (value) {
        if (value.isEmpty) {
          return 'Fee cannot be empty';
        } else {
          return null;
        }
      },
    );

    addFee = RaisedButton(
      shape: RoundedRectangleBorder(
        borderRadius: BorderRadius.circular(5.0),
      ),
      onPressed: () {
        _submit();
      },
      padding: EdgeInsets.all(12),
      color: Colors.redAccent,
      child: Text('Add Payment',
          style: TextStyle(color: Colors.white, fontSize: 24.0)),
    );

    return Scaffold(
      key: addFeesScaffoldKey,
      body: new Form(
        key: addFeesFormKey,
        child: Center(
            child: ListView(
                shrinkWrap: true,
                padding: EdgeInsets.only(left: 24.0, right: 24.0),
                children: <Widget>[
              SizedBox(
                height: 25.0,
              ),
              fees,
              SizedBox(
                height: 15.0,
              ),
              addFee
            ])),
      ),
    );
  }
}

这是怎么回事?

您需要将 _fees = val 放入 setState - 参见示例:

fees = TextFormField(
      keyboardType: TextInputType.number,
      onSaved: (val) => setState(() => _fees = val), // This is change
      decoration: InputDecoration(labelText: 'Fees'),
      validator: (value) {
        if (value.isEmpty) {
          return 'Fee cannot be empty';
        } else {
          return null;
        }
      },
    );

最后,我想通了,解决方案非常简单。

解决方法:在尝试访问variables之前调用form.save();解决问题。

我在 void _submit() 方法中交换了两行以使其工作,这里是 更新的代码:

void _submit() {
  final form = addFeesFormKey.currentState;

  if (form.validate()) {
    setState(() {
      form.save(); //swapped
      print(_fees);
    });
  }
}