6 表单组件

表单是一个包含表单元素的区域。表单元素允许用户输入内容,比如:文本域、下拉列表、单选框、复选框等。常见的应用场景有:登录、注册、输入信息等。表单里有两个重要的组件,一个是Form组件用来做整个表单提交使用的,另一个是TextFormField组件用来做用户输入的。 先来看看Form组件的属性,如下所示:

对于输入框我们最关心的是输入内容是否合法,比如邮箱地址是否正确,电话号码是否是数字,等等。等用户输入完成后,需要知道输入框输入的内容。 为了获取表单的实例,我们需要设置一个全局类型的key,通过这个key的属性,来获取表单对象。需要使用GlobalKey来获取,代码如下所示:

GlobalKey<FormState> loginKey = new GlobalKey<FormState>();

接下来编写一个简单的登录界面,其中有用户名,密码输入框再加上一个登录按钮。当用户没有输入任何内容时,输入提示“请输入用户名 请输入密码”,如图4-12所示。当用户正常输入内容点击“登录”按钮,界面不发生任何变化,表示输入内容正常。这里可以尝试输入一个非法的数据,比如验证代码里要求密码必需为6位,当你输入6位以下时,再次点击“登录”,会报一个错误提示信息“密码长度不够6位”,如图4-13所示。 完整示例代码如下所示:

import 'package:flutter/material.dart';

void main() => runApp(new LoginPage());

class LoginPage extends StatefulWidget {
  @override
  _LoginPageState createState() => new _LoginPageState();
}

class _LoginPageState extends State<LoginPage> {

  //全局Key用来获取Form表单组件
  GlobalKey<FormState> loginKey = new GlobalKey<FormState>();
  //用户名
  String userName;

  //密码
  String password;

  void login() {
    //读取当前的Form状态
    var loginForm = loginKey.currentState;

    //验证Form表单
    if (loginForm.validate()) {
      loginForm.save();
      print('userName:' + userName + ' password:' + password);
    }
  }

  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: 'Form表单示例',
      home: new Scaffold(
        appBar: new AppBar(
          title: new Text('Form表单示例'),
        ),
        body: new Column(
          children: <Widget>[
            new Container(
              padding: const EdgeInsets.all(16.0),
              child: new Form(
                key: loginKey,
                child: new Column(
                  children: <Widget>[
                    new TextFormField(

                      decoration: new InputDecoration(
                        labelText: '请输入用户名',
                      ),
                      onSaved: (value) {
                        userName = value;
                      },
                      onFieldSubmitted: (value){

                      },
                    ),
                    new TextFormField(
                      decoration: new InputDecoration(
                        labelText: '请输入密码',
                      ),
                      obscureText: true,
                      //验证表单方法
                      validator: (value) {
                        return value.length < 6 ? "密码长度不够6位" : null;
                      },
                      onSaved: (value) {
                        password = value;
                      },
                    ),
                  ],
                ),
              ),
            ),
            new SizedBox(
              width: 340.0,
              height: 42.0,
              child: new RaisedButton(
                onPressed: login,
                child: new Text(
                    '登录',
                  style: TextStyle(
                    fontSize: 18.0,
                  ),
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }
}