Flutter学习笔记(13)--表单组件
如需转载,请注明出处:Flutter学习笔记(13)--表单组件
表单组件是个包含表单元素的区域,表单元素允许用户输入内容,比如:文本区域,下拉表单,单选框、复选框等,常见的应用场景有:登陆、注册、输入信息等。表单里有两个重要的组件,一个是Form组件用来做整个表单提交使用的,另一个是TextFormField组件用来做用户输入的。
| 属性 | 类型 | 说明 |
| Key | Key | 组件在整个Widget树中的key值 |
| autovalidate | bool | 是否自动提交表单 |
| child | Widget | 组件child只能有一个组件 |
| onChange | VoidCallback | 当FormField值改变时的回调函数 |
| 属性名 | 类型 | 说明 |
| autovalidate | bool | 自动验证值 |
| initalValue | T | 表单字段初始值,比如:输入收获地址时,默认回填本的地址信息 |
| onSaved | FormFieldSetter<T> | 当Form表单调用保存方法Save时回调的函数 |
| validator | FormFieldValidator<T> | Form表单验证器 |
对于输入框我们最关心的时输入内容是否合法,比如邮箱地址是否正确,电话号码是否是数字等等,等用户输入完成后,我们需要知道输入框输入的内容。那么我们要如何才能获取到表单对象呢?为了获取表单的实例,我们需要设置一个全局类型的key,通过这个key的属性,来获取表单对象:
GlobalKey<FormState> globalKey = new GlobalKey<FormState>();
我们来简单的写一个登陆页面,校验输入框内的内容,当内容不合法时,并给出相应的提示:
import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart'; void main() => runApp(DemoApp()); class DemoApp extends StatefulWidget{
@override
_DemoAppState createState() => new _DemoAppState();
} class _DemoAppState extends State<DemoApp> {
String userName;
String userPwd;
GlobalKey<FormState> globalKey = new GlobalKey<FormState>();
void check(){
var loginForm = globalKey.currentState;
//验证表单
if(loginForm.validate()){
loginForm.save();
Fluttertoast.showToast(msg: '信息提交成功',toastLength: Toast.LENGTH_LONG,gravity: ToastGravity.BOTTOM,textColor: Colors.white);
}
}
@override
Widget build(BuildContext context) {
return new MaterialApp(
debugShowCheckedModeBanner: false,
title: 'From表单Demo',
home: new Scaffold(
appBar: new AppBar(
title: new Text('Form表单Demo'),
leading: Icon(Icons.menu,size: ,),
actions: <Widget>[
IconButton(icon: Icon(Icons.search),iconSize: , onPressed: null)
],
),
body: new Column(
children: <Widget>[
new Form(
key: globalKey,
child: new Column(
children: <Widget>[
new TextFormField(
decoration: new InputDecoration(
labelText: '请输入用户名',
),
onSaved: (value){
userName = value;
},
),
new TextFormField(
decoration: new InputDecoration(
contentPadding: EdgeInsets.only(left: ,top: ,right: ,bottom: ),
hintText: '请输入密码',
hintStyle: new TextStyle(fontSize: ,color: Colors.amberAccent)
),
obscureText: true,
validator: (value){
return value.length < ? '密码长度不够6位' : null;
},
onSaved: (value){
userPwd = value;
},
)
],
),
),
new Container(
margin: new EdgeInsets.symmetric(vertical: ,horizontal: ),
width: ,
height: ,
child: new SizedBox(
child: new RaisedButton(
onPressed: check,
child: new Text(
'确定',
style: new TextStyle(
fontSize: ,
color: Colors.white
),
),
),
),
)
],
),
),
);
}
}
先看一下上面代码的效果截图,然后我会给大家讲一下代码的内容

写的比较丑,大家见谅,主要是因为我想多试试一些属性怎么用,总之是要多尝试嘛~
上面是输入内容前和输入内容后的对比图,从直观的表象上可以看的出来,用户名输入框输入内容后,提示内容被挤到上面去了,而密码输入框输入内容后提示内容则消失了,这是因为两个输入框提示语的text的类型使用的不同,用户名:labelText,密码:hintText,这两个都有style属性,都可以对默认的提示内容字体进行属性设置。在点击确认按钮后,会调用check()方法,在check()方法中提交表单验证,这时候会触发密码输入框中的validator: (value),从而实现我们密码输入框内容的校验,这个就是TextFromField中的验证回调方法,在表单验证的时候,会先验证这个方法中的逻辑判断,如果验证失败返回错误信息,如果验证通过则返回null。
接下来的内容有兴趣的可以继续看一下,我想以Android中写xml的布局方式理解一下Flutter中的页面构建,因为我前面一直是在写简单的组件Demo,还没有形成一个完整的构建意识,以下是我个人的理解,如果有不对的地方,还请留言批评、指正,不胜感谢!!!
从整个页面来构思的话,可以看做是一个大容器,容器里面有三个组件,分别是两个输入框和一个按钮,这3个组件是垂直方向排列的,写Android的同学看到这个页面,很容易就会想到最外层放一个Linearlayout或者是一个RelativeLayout,然后在里面垂直方向放上两个EditText和一个Button,再写一下控件的属性的就完事儿了,其实写Flutter也是这种思想。
注:在这里我先说明以下在Flutter中child里面只能放一个Widget,Children可以放多个Widget。
我们来把Android和Flutter对比着理解,这样应该可以更容易理解一点,也更直观一点:
1.Android:最外层垂直方向的Linearlayout或RelativeLayout。
Flutter:最外层body我们new了一个Column(Column也是一个容器,类似于Container)
2.Android:放上两个EditText和一个Button
Flutter:容器放置好了,我们要开始往容器里面加组件元素了,因为容器里面我们要放置多个组件,所以我们要使用children,children里面放一个Form表单和一个button,在Form表单里面,我们要放两个输入框,而且是垂直方向放置的,想到这里是不是就该先考虑怎么把方向设置好呢?所以Form表单里的第一层widget就要放置一个Column容器,容器里面放两个输入框,既然是两个,那么是不是两个输入框就应该被一个children包裹起来呢?
总的来说:根widget(column)->children(里面包含Form和button)->Form表单(第一层)->child(column)->children(里面包含了两个输入框TextFormField)->TextFormField(第三层)
最后看一下按钮部分的代码,说明一下为什么外面要包一层Container
new Container(
margin: new EdgeInsets.symmetric(vertical: ,horizontal: ),
width: ,
height: ,
child: new SizedBox(
child: new RaisedButton(
onPressed: check,
child: new Text(
'确定',
style: new TextStyle(
fontSize: ,
color: Colors.white
),
),
),
),
)
之所以最外层包了个Container,是因为SizedBox和RaiseButton这两个组件都没有margin或padding属性,所以UI上要想控制边距等操作,这是一种处理方式。
也不知道我上面大白话写了那么多,能不能表达清楚我的意思,如果有没看懂的,还麻烦留言提问吧!!!
下一章节:Flutter学习笔记(14)--StatefulWidget简单使用
Flutter学习笔记(13)--表单组件的更多相关文章
- Flutter学习笔记(9)--组件Widget
如需转载,请注明出处:Flutter学习笔记(9)--组件Widget 在Flutter中,所有的显示都是Widget,Widget是一切的基础,我们可以通过修改数据,再用setState设置数据(调 ...
- Bootstrap学习笔记(二) 表单
在Bootstrap学习笔记(一) 排版的基础上继续学习Bootstrap的表单,编辑器及head内代码不变. 3-1 基础表单 单中常见的元素主要包括:文本输入框.下拉选择框.单选按钮.复选按钮.文 ...
- AngularJS 1.2.x 学习笔记(表单校验篇)
https://my.oschina.net/cokolin/blog/526911 摘要: 本文首发于 blog.csdn.net/vipshop_ebs/article/details/39472 ...
- Symfony2学习笔记之表单
对于一个Web开发者来说,处理HTML表单是一个最为普通又具挑战的任务.Symfony2集成了一个Form组件,让处理表单变的容易起来.在这一节里,我们将从基础开始创建一个复杂的表单,学习表单类库中最 ...
- vue学习笔记(六)表单输入绑定
前言 在上一章vue学习笔记(四)事件处理器这一篇博客的内容中,我们已经了解vue是如何绑定事件的,而本篇博客主要讲解的是vue中表单输入的绑定,通常我们自己提交信息的时候都是通过表单将信息到服务器的 ...
- angular2 学习笔记 ( Form 表单 )
refer : https://angular.cn/docs/ts/latest/guide/forms.html https://angular.cn/docs/ts/latest/cookboo ...
- Vue学习笔记之表单绑定输入
vue的核心:声明式的指令和数据的双向绑定. 那么声明式的指令,已经给大家介绍完了.接下来我们来研究一下什么是数据的双向绑定? 另外,大家一定要知道vue的设计模式:MVVM M是Model的简写,V ...
- jQuery学习笔记2——表单操作
一.获取和设置表单的值:val()和text() 1. 获取表单的值: $("#username").val(); 2. 设置表单的值: $("#username&quo ...
- [学习笔记]--Jfinal 表单提交附件
近期.项目里面用到了Jfinal 里面的上传附件. Jfinal 的Controller 里面提供了一个 getFile系列方法提供文件上传. 我这里呢,是文件上传和表单參数一起提交. 页面类似下图: ...
- 20151223jquery学习笔记--Ajax表单提交
传统的表单提交, 需要多次跳转页面, 极大的消耗资源也缺乏良好的用户体验. 而这款form.js 表单的 Ajax 提交插件将解决这个问题.一. 核心方法官方网站: http://malsup.com ...
随机推荐
- 基于uReplicator复制的kafka主备集群间的切换策略
一.概述 目前基于中间件uReplicator实现了kafka集群间的迁移复制,可以实现跨区.跨云的kafka集群间复制同步,也可以实现kafka集群的冷热互备架构:在实现集群间同步以后,需要解决一个 ...
- Hive 学习之路(六)—— Hive 视图和索引
一.视图 1.1 简介 Hive 中的视图和RDBMS中视图的概念一致,都是一组数据的逻辑表示,本质上就是一条SELECT语句的结果集.视图是纯粹的逻辑对象,没有关联的存储(Hive 3.0.0引入的 ...
- java源码解析之String类(二)
上一节主要介绍了String类的一些构造方法,主要分为四类 无参构造器:String(),创建一个空字符串"",区别于null字符串,""已经初始化,null并 ...
- 用arduino制作具有无限数据传输功能的气象站
本项目是用arduino开源硬件,来快速制作具有无限数据传输功能的气象站,我之前做过一个带数据记录功能的气象站项目,这次算是升级和改进的版本. 第1步:构想 首先,需要增加从气象站到室内接收器的无线数 ...
- 【协议】TCP与UDP
转载地址:https://blog.csdn.net/qq_34988624/article/details/85856848 1.为什么会有TCP/IP协议 在世界上各地,各种各样的电脑运行着各自不 ...
- [Qt]自定义表头实现过滤功能
1. 写在前面 过滤功能源自项目上交互优化用户体验,在表头添加过滤符号实现过滤,替换以往在表格上方占用一行过滤项进行过滤. 2. 过滤提示 过滤提示就是三态图标(normal,hover,press) ...
- 小白开学Asp.Net Core 《六》
小白开学Asp.Net Core <六> —— 探究.Net Core 跨平台的奥秘 1.写这篇文章的初衷 有好多朋友反馈看不懂我写的开源的一个练手项目(GitHub:https://gi ...
- 【朝花夕拾】Android自定义View篇之(十)TouchSlop及VelocityTracker
前言 在Android事件中,有几个比较基本的概念和知识点需要掌握.比如,表示最小移动阈值的TouchSlop,追踪事件速度的VelocityTracker,用于检测手势的GestureDetecto ...
- Bzoj 2058: [Usaco2010 Nov]Cow Photographs 题解
2058: [Usaco2010 Nov]Cow Photographs Time Limit: 3 Sec Memory Limit: 64 MBSubmit: 190 Solved: 104[ ...
- 从四个属性的角度来理解C语言的指针也许会更好理解
文章会在文末更新! 关于指针是什么,很多教材已经作出了定义,大多数都会定义为"存放变量内存地址的变量".从这句话中我觉得除了让我知道这个定义有11个字以外,其他就没什么用了.我个人 ...