当前位置:网站首页>Flutter 从零开始 008 表单
Flutter 从零开始 008 表单
2022-06-30 10:46:00 【华为云】
表单Form
在实际业务开发中,在正式像服务器提交数据之前,都会对各个输入框数据进行合法性校验,但是对每一个TextField 都进行校验是一件很麻烦的事。如果用户想清除一组TextField 的数据,又非常的麻烦。flutter还给我们提供了一个From 组件,它可以对输入框进行分组,然后进行统一操作,如内容校验,输入框重置,输入内容保存等。
Form继承自StatefulWidget对象,它对应的状态类为FormState。我们先看看Form类的定义:
Form({ required Widget child, bool autovalidate = false, WillPopCallback onWillPop, VoidCallback onChanged,})autovalidate : 是否自动校验输入内容,当为true 时,每个子FormFeild 内容发生变化时,都会自动校验合法性,并直接显示错误信息。否则,需要通过调用FormState.validate() 来手动校验。
onWillPop: 决定Form 所在的路由是否可以直接返回(如点击返回按钮),该回调返回一个Future对象,如果 Future 的最终结果是false,则当前路由不会返回;如果为true,则会返回到上一个路由。此属性通常用于拦截返回按钮。
onChanged:Form的任意一个子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为Form的State类,可以通过Form.of()或GlobalKey获得。我们可以通过它来对Form的子孙FormField进行统一操作。我们看看其常用的三个方法:
FormState.validate():调用此方法后,会调用Form子孙FormField的validate回调,如果有一个校验失败,则返回false,所有校验失败项都会返回用户返回的错误提示。
FormState.save():调用此方法后,会调用Form子孙FormField的save回调,用于保存表单内容
FormState.reset():调用此方法后,会将子孙FormField的内容清空。
示例
我们修改一下上面用户登录的示例,在提交之前校验:
用户名不能为空,如果为空则提示“用户名不能为空”。
密码不能小于 6 位,如果小于 6 为则提示“密码不能少于 6 位”。
class _MyHomePageState extends State<MyHomePage> { TextEditingController userController = TextEditingController(); TextEditingController passController = TextEditingController(); GlobalKey _globalKey = GlobalKey<FormState>(); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text(widget.title), ), body: Form( key: _globalKey, //设置globalKey,用于后面获取FormState autovalidateMode: AutovalidateMode.onUserInteraction, child: Column( children: [ TextFormField( autofocus: true, controller: userController, decoration: InputDecoration( labelText: "用户名", hintText: "用户名或邮箱", icon: Icon(Icons.person), ), validator: (v) { return v!.trim().isNotEmpty ? null : '用户名不能为空'; }, ), SizedBox( height: 20, ), TextFormField( controller: passController, decoration: InputDecoration( labelText: "密码", hintText: "输入密码", icon: Icon(Icons.lock), ), obscureText: true, validator: (v) { return v!.trim().length > 5 ? null : '密码不能少于6位'; }, ), Padding( padding: EdgeInsets.only(top: 20), child: Expanded( child: ElevatedButton( child: Padding( padding: EdgeInsets.all(16), child: Text("登录"), ), onPressed: () { // 通过_formKey.currentState 获取FormState后, // 调用validate()方法校验用户名密码是否合法,校验 // 通过后再提交数据。 if((_globalKey.currentState as FormState).validate()){ print("验证通过,开始提交"); } }, ), ), ), ], ), ), ); }}运行效果如下

注意,登录按钮的onPressed方法中不能通过Form.of(context)来获取,原因是,此处的context为FormTestRoute的context,而Form.of(context)是根据所指定context向根去查找,而FormState是在FormTestRoute的子树中,所以不行。正确的做法是通过Builder来构建登录按钮,Builder会将widget节点的context作为回调参数:
Expanded( // 通过Builder来获取ElevatedButton所在widget树的真正context(Element) child:Builder(builder: (context){ return ElevatedButton( ... onPressed: () { //由于本widget也是Form的子代widget,所以可以通过下面方式获取FormState if(Form.of(context).validate()){ //验证通过提交数据 } }, ); }))下一节我们将介绍指示器
边栏推荐
- 8行代码实现快速排序,简单易懂图解!
- 【leetcode 16】三数之和
- 100 important knowledge points that SQL must master: Combined Query
- iptables目标TPROXY
- Pytorch notes: validation, model eval V.S torch. no_ grad
- Double-DQN笔记
- LVGL 8.2 Image
- 林克庆到番禺区调研“发展要安全”工作 以“时时放心不下”责任感抓好安全发展各项工作
- pytorch 筆記 torch.nn.BatchNorm1d
- Pytorch Notebook. Nn. Batchnorm1d
猜你喜欢

8行代码实现快速排序,简单易懂图解!

Wireguard simple configuration

File sharing server

Deep dive kotlin synergy (16): Channel

【STL源码剖析】容器(待补充)

The jetpack compose dropdownmenu is displayed following the finger click position

电商两位大佬花边新闻刷屏,代表电商回归正常,将有利于实体经济

pytorch 筆記 torch.nn.BatchNorm1d

ESP32-C3入门教程 问题篇⑨——Core 0 panic‘ed (Load access fault). Exception was unhandled. vfprintf.c:1528

Mysql database foundation: views and variables
随机推荐
pytorch 筆記 torch.nn.BatchNorm1d
【leetcode 239】滑动窗口
The reasoning delay on iphone12 is only 1.6 MS! Snap et al. Analyzed the transformer structure latency in detail, and used NAS to find out the efficient network structure of mobile devices
What is erdma as illustrated by Coptic cartoon?
The intelligent DNA molecular nano robot model is coming
Collectors. Tomap application
科普达人丨漫画图解什么是eRDMA?
OLAP数据库引擎如何选型?
100 important knowledge points that SQL must master: using table aliases
数学知识复习:第二型曲线积分
ESP32-C3入门教程 IoT篇⑤——阿里云 物联网平台 EspAliYun RGB LED 实战之批量生产的解决方案
线代(高斯消元法、线性基)
100 important knowledge points that SQL must master: updating and deleting data
LeetCode Algorithm 86. 分隔链表
pytorch 笔记 torch.nn.BatchNorm1d
Pytorch notes torch nn. BatchNorm1d
LVGL 8.2图片缩放及旋转
我们公司使用 7 年的这套通用解决方案,打通了几十个系统,稳的一批!
From introduction to mastery of MySQL 50 lectures (32) -scylladb production environment cluster building
LED driver library based on Hal Library