Flutter组件学习(8)表单Form

Form介绍

实际业务中,在正式向服务器提交数据前,都会对各个输入框数据进行合法性校验,但是对每一个TextField都分别进行校验将会是一件很麻烦的事。还有,如果用户想清除一组TextField的内容,除了一个一个清除有没有什么更好的办法呢?为此,Flutter提供了一个Form 组件,它可以对输入框进行分组,然后进行一些统一操作,如输入内容校验、输入框重置以及输入内容保存。

Form继承自StatefulWidget对象,它对应的状态类为FormState

  • autovalidate:是否自动校验输入内容;当为true时,每一个子FormField内容发生变化时都会自动校验合法性,并直接显示错误信息。否则,需要通过调用FormState.validate()来手动校验。
  • onWillPop:决定Form所在的路由是否可以直接返回(如点击返回按钮),该回调返回一个Future对象,如果Future的最终结果是false,则当前路由不会返回;如果为true,则会返回到上一个路由。此属性通常用于拦截返回按钮。
  • onChangedForm的任意一个子FormField内容发生变化时会触发此回调。

FormField

Form的子孙元素必须是FormField类型,FormField是一个抽象类,定义几个属性,FormState内部通过它们来完成操作,FormField部分定义如下:

const FormField({
  ...
  FormFieldSetter<T> onSaved, //保存回调
  FormFieldValidator<T>  validator, //验证回调
  T initialValue, //初始值
  bool autovalidate = false, //是否自动校验。
})

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

FormState

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

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

demo

登录页面,输入账号,密码,然后点击登录按钮判断账号是否存在,密码是否正确

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';

void main() {
  runApp(FormApp());
}

class FormApp extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    return FormTest();
  }
}

class FormTest extends State {
  TextEditingController _phoneController = new TextEditingController();
  TextEditingController _passController = new TextEditingController();

  GlobalKey _formKey = new GlobalKey<FormState>();

  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          backgroundColor: Colors.red,
          title: Text(
            'Form表单练习',
            style: TextStyle(fontSize: 18, color: Colors.yellow),
          ),
        ),
        body: Column(
          children: <Widget>[
            Container(
              margin: EdgeInsets.all(30),
              child: Form(
                key: _formKey, //设置globalKey,用于后面获取FormState
                child: Column(
                  children: <Widget>[
                    TextFormField(
                        autovalidate: true,
                        //开启自动校验
                        validator: (v) {
                          return v.trim().length > 0 ? null : '手机号不能为空';
                        },
                        keyboardType: TextInputType.phone,
                        controller: _phoneController,
                        decoration: InputDecoration(
                          icon: Icon(Icons.phone),
                          filled: true,
                          fillColor: Colors.yellow,
                          hintText: "手机号",
                          border: OutlineInputBorder(
                              borderRadius: BorderRadius.circular(20),
                              borderSide:
                                  BorderSide(color: Colors.blue, width: 1)),
                        )),
                    SizedBox(height: 10),
                    TextFormField(
                        validator: (v) {
                          return v.trim().length > 5 ? null : '密码不能少于6位';
                        },
                        controller: _passController,
                        keyboardType: TextInputType.visiblePassword,
                        obscureText: true,
                        decoration: InputDecoration(
                          icon: Icon(Icons.lock),
                          filled: true,
                          fillColor: Colors.yellow,
                          border: OutlineInputBorder(
                              borderRadius: BorderRadius.circular(20),
                              borderSide:
                                  BorderSide(color: Colors.blue, width: 1)),
                        )),
                    SizedBox(height: 10),
                    Row(
                      mainAxisAlignment: MainAxisAlignment.center,
                      children: <Widget>[
                        FlatButton(
                          onPressed: () {
                            (_formKey.currentState as FormState).reset();
                            //获取数据
                            this.setState(() {});
                          },
                          color: Colors.blue,
                          child: Text(
                            '重置',
                            style: TextStyle(color: Colors.white, fontSize: 18),
                          ),
                        ),
                        SizedBox(
                          width: 30,
                        ),
                        FlatButton(
                          onPressed: () {
                            if ((_formKey.currentState as FormState)
                                .validate()) {
                              //验证通过提交数据
                            }

                            //获取数据
                            this.setState(() {});
                          },
                          color: Colors.blue,
                          child: Text(
                            '登录',
                            style: TextStyle(color: Colors.white, fontSize: 18),
                          ),
                        )
                      ],
                    ),
                    SizedBox(
                      height: 20,
                    ),
                    Text(
                      '账号是:${_phoneController.text}\n密码是:${_passController.text}',
                      style: TextStyle(
                          fontSize: 20,
                          color: Colors.blue,
                          fontWeight: FontWeight.w700),
                    )
                  ],
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

运行效果

这里我有一个疑问,期待解决,就是当我正确输入之后,点击登录,然后再点击重置 ,是没有办法清空的,如果有大神看到这个问题,还请赐教,万分感谢~

 

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小小苏的小小苏

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值