在实际业务中,前端在提交数据前都应该验证下数据的基本合法性,如果使用TextField进行验证需要写很多的方法进行判断就显得非常麻烦。那有更加方便的组件吗?肯定有,这就是这节介绍的Form组件。Form组件就可以对验证进行统一控制,也就方便了我们写代码。但是一般Form表单都是与TextFormField组件组合使用。下面我们就来介绍:

Form组件是一个容器类控件,可以包含多个FormField表单控件,这样的好处是统一管理。

  • onWillPop:决定Form所在的路由是否可以直接返回(如点击返回按钮),该回调返回一个Future对象,如果Future的最终结果是false,则当前路由不会返回;如果为true,则会返回到上一个路由。此属性通常用于拦截返回按钮。
  • onChanged:Form的任意一个子FormField内容发生变化时会触发此回调。

在使用Form的时候需要设置其key,通过key获取当前的FormState,然后可以调用FormState的save、validate、reset等方法,一般通过如下方法设置:

final _formKey = GlobalKey<FormState>();
Form(
    key: _formKey,
    ...
)

获取FormState并调用相关方法:

var _state = _formKey.currentState;
if(_state.validate()){
  _state.save();
}

为了方便使用,Flutter提供了一个TextFormField组件,它继承自FormField类,也是TextField的一个包装类,所以除了FormField定义的属性之外,它还包括TextField的属性。

FormState为Form的State类,可以通过Form.of()或GlobalKey获得。我们可以通过它来对Form的FormField进行统一操作。我们看看其常用的三个方法:

  • FormState.validate():调用此方法后,会调用Form的FormField的validate回调,如果有一个校验失败,则返回false,所有校验失败项都会返回用户返回的错误提示。
  • FormState.save():调用此方法后,会调用Form的FormField的save回调,用于保存表单内容
  • FormState.reset():调用此方法后,会将FormField的内容清空。

代码实现

import 'package:flutter/material.dart';

class FormBaseWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    String _name = ""; //用户名
    String _password = ""; //密码
    GlobalKey _formKey = new GlobalKey<FormState>();
    return Scaffold(
      appBar: AppBar(
        title: Text('表单组件:Form和TextFormField'),
        elevation: 0.0,
        centerTitle: true,
      ),
      body: Form(
          key: _formKey,
          onChanged: () {
            print("内部组件发生改变");
          },
          onWillPop: () async {
            print("返回处理");
            return true;
          },
          child: Column(
            children: [
              TextFormField(
                keyboardType: TextInputType.emailAddress,
                autofocus: true,
                decoration: InputDecoration(
                  labelText: "用户名",
                  icon: Icon(Icons.person),
                  hintText: "请输入用户名",
                ),
                validator: (value) {
                  if (value!.isEmpty) {
                    return "用户名不能为空";
                  }
                },
                onSaved: (value) {
                  _name = value.toString();
                  print("保存用户名:" + _name);
                },
              ),
              TextFormField(
                obscureText: true,
                decoration: InputDecoration(
                  icon: Icon(Icons.lock),
                  hintText: "请输入密码",
                  labelText: "密码",
                ),
                validator: (value) {
                  if (value!.trim().isEmpty) {
                    return "密码不能为空";
                  }
                },
                onSaved: (value) {
                  _password = value.toString();
                  print("保存密码:" + _password);
                },
              ),
              Row(
                mainAxisAlignment: MainAxisAlignment.center,
                children: [
                  TextButton(
                    onPressed: () {
                      //验证表单数据
                      var _state = _formKey.currentState as FormState;
                      if (_state.validate()) {
                        _state.save();
                      } else {
                        print("验证失败");
                      }
                    },
                    child: Text("提交"),
                  ),
                  TextButton(
                    onPressed: () {
                      //清除表单数据
                      var _state = _formKey.currentState as FormState;
                      _state.reset();
                    },
                    child: Text("重置"),
                  )
                ],
              )
            ],
          )),
    );
  }
}

图片alt