flutter 基础容器wdiget TextField Form FormField FormState

1.属性

const TextField({

Key key,
TextEditingController controller, //编辑框的控制器,通过它可以设置/获取编辑框的内容、选择编辑内容、监听编辑文本改变事件。大多数情况下我们都需要显式提供一个controller来与文本框交互。如果没有提供controller,则TextField内部会自动创建一个

FocusNode focusNode, // 用于控制TextField是否占有当前键盘的输入焦点。它是我们和键盘交互的一个handle

InputDecoration decoration: const InputDecoration(), //于控制TextField的外观显示,如提示文本、背景颜色、边框

TextInputType keyboardType,  // 用于设置该输入框默认的键盘输入类型,取值如下:

| TextInputType枚举值 | 含义 | | ------------------- | --------------------------------------------------- | | text | 文本输入键盘 | | multiline | 多行文本,需和maxLines配合使用(设为null或大于1) | | number | 数字;会弹出数字键盘 | | phone | 优化后的电话号码输入键盘;会弹出数字键盘并显示"* #" | | datetime | 优化后的日期输入键盘;Android上会显示“: -” | | emailAddress | 优化后的电子邮件地址;会显示“@ .” | | url | 优化后的url输入键盘; 会显示“/ .” |

TextInputAction textInputAction, // 键盘动作按钮图标(即回车键位图标),它是一个枚举值,有多个可选值

TextCapitalization textCapitalization: TextCapitalization.none,
TextStyle style,  //正在编辑的文本样式
TextAlign textAlign: TextAlign.start, //输入框内编辑文本在水平方向的对齐方式
bool autofocus: false, //是否自动获取焦点
bool obscureText: false, //是否隐藏正在编辑的文本,如用于输入密码的场景等,文本内容会用“•”替换
bool autocorrect: true,
int maxLines: 1,  //输入框的最大行数,默认为1;如果为null,则无行数限制
int maxLength,  // maxLength代表输入框文本的最大长度,设置后输入框右下角会显示输入的文本计数
bool maxLengthEnforced: true,  // maxLengthEnforced决定当输入文本长度超过maxLength时是否阻止输入,为true时会阻止输入,为false时不会阻止输入但输入框会变红

ValueChanged<String> onChanged,  // 输入框内容改变时的回调函数
VoidCallback onEditingComplete,  //输入框输入完成时触发,接收当前输入内容做为参数
ValueChanged<String> onSubmitted, //输入框输入完成时触发,无参数
List<TextInputFormatter> inputFormatters, //用于指定输入格式;当用户输入内容改变时,会根据指定的格式来校验

bool enabled,  //如果为false,则输入框会被禁用,禁用状态不接收输入和事件,同时显示禁用态样式

//自定义输入框光标宽度、圆角和颜色
double cursorWidth: 2.0,
Radius cursorRadius,
Color cursorColor,

Brightness keyboardAppearance,
EdgeInsets scrollPadding: const EdgeInsets.all(20.0)
})

2.用户名密码输入框

import 'package:flutter/material.dart';

class MyInput extends StatelessWidget{
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text("TextField"),),
      body: Column(children: <Widget>[
        //用户名
        TextField(
          autofocus: true,
          decoration: InputDecoration(
            labelText: "用户名",
            hintText: "请输入用户名和密码",
            hintStyle: TextStyle(fontSize: 12.0,color: Colors.grey),
            labelStyle: TextStyle(
              color: Colors.blueGrey,
              fontSize: 16.0,
              fontStyle: FontStyle.italic
            ),
            prefixIcon: Icon(Icons.person)
          ),
        ),
        //密码
        TextField(
          obscureText: true,
          decoration: InputDecoration(
            labelText: "密码",
            hintText: "请输入密码",
            hintStyle: TextStyle(fontSize: 12.0,color: Colors.grey),
            labelStyle: TextStyle(
              color: Colors.blueGrey,
              fontSize: 16.0,
              fontStyle: FontStyle.italic
            ),
            prefixIcon: Icon(Icons.lock)
          ),
        )
      ],),
    );
  }
  
}

     

3.获取输入框的值,两种方式

  1. 定义两个变量,用于保存用户名和密码,然后在onChange触发时,各自保存一下输入内容。
  2. 通过controller直接获取
import 'package:flutter/material.dart';


TextEditingController nameCtrl=new TextEditingController();

class MyInput extends StatefulWidget{
  @override
  _MyInputState createState() {
    // TODO: implement createState
    return _MyInputState();
  }
}

class _MyInputState extends State<MyInput>{
 String _userName; //用户名

 //获取用户名
 _setUserName(val){
   setState(() {
     _userName=val;
   });
 }

 @override
 Widget build(BuildContext context) {

    return Scaffold(
      appBar: AppBar(title: Text("TextField"),),
      body:Column(children: <Widget>[
        TextField(
          controller: nameCtrl,
          autofocus: true,

          //监听文本的变化
          onChanged:(val){
            _setUserName(val);
          },
          decoration: InputDecoration(
            labelText: "用户名",
            hintText: "请输入用户名和密码",
            hintStyle: TextStyle(fontSize: 12.0,color: Colors.grey),
            labelStyle: TextStyle(
              color: Colors.blueGrey,
              fontSize: 16.0,
              fontStyle: FontStyle.italic
            ),
            prefixIcon: Icon(Icons.person)
          ),
        ),
        TextField(
          obscureText: true,
          decoration: InputDecoration(
            labelText: "密码",
            hintText: "请输入密码",
            hintStyle: TextStyle(fontSize: 12.0,color: Colors.grey),
            labelStyle: TextStyle(
              color: Colors.blueGrey,
              fontSize: 16.0,
              fontStyle: FontStyle.italic
            ),
            prefixIcon: Icon(Icons.lock)
          ),
        ),
        RaisedButton(
          child: Text("获取TextField的值"),
          onPressed: (){
            //第三个字符开始选中后面的字符
            nameCtrl.selection=TextSelection(
                   baseOffset: 2,
                   extentOffset: nameCtrl.text.length
            );
            print("userName state获取数据:$_userName");
            print("control获取数据:${nameCtrl.text}");
          },
        )
      ],)
    );
  }
  
}

4.Form,FormField,FormState

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

Form({

  @required Widget child,

  bool autovalidate = false, //是否自动校验输入内容;当为true时,每一个子FormField内容发生变化时都会自动校验合法性,并直接显示错误信息。否则,需要通过调用FormState.validate()来手动校验

  WillPopCallback onWillPop, // 决定Form所在的路由是否可以直接返回(如点击返回按钮),该回调返回一个Future对象,如果Future的最终结果是false,则当前路由不会返回;如果为true,则会返回到上一个路由。此属性通常用于拦截返回按钮

  VoidCallback onChanged, //Form的任意一个子FormField内容发生变化时会触发此回调
})



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

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

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

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

FormState.validate():调用此方法后,会调用Form子孙FormField的validate回调,如果有一个校验失败,则返回false,所有校验失败项都会返回用户返回的错误提示

FormState.save():调用此方法后,会调用Form子孙FormField的save回调,用于保存表单内容

FormState.reset():调用此方法后,会将子孙FormField的内容清空
1.用户名不能为空,如果为空则提示“用户名不能为空”。
2.密码不能小于6位,如果小于6为则提示“密码不能少于6位”。

import 'package:flutter/material.dart';

class MyInput extends StatefulWidget{
  @override
  _MyInputState createState()=>_MyInputState();
}

class _MyInputState extends State<MyInput>{

String _fmResult;  //成功失败提示

int _count=0; //成功计数

GlobalKey _formKey=new GlobalKey<FormState>(); //定义 FormState

TextEditingController _nameCtrl=new TextEditingController(); // 用户名的control
TextEditingController _pwdCtrl=new TextEditingController(); //密码的control


 _setResult(val){
   setState(() {
     _count++;
     _fmResult=val;
   });
 }

Widget _fmUserNameWidget(){
  return TextFormField(
       controller: _nameCtrl, // 用于获取用户名值
       decoration: InputDecoration(
          labelText: "用户名",
          hintText: "请输入用户名和密码",
          hintStyle: TextStyle(fontSize: 12.0,color: Colors.grey),
          labelStyle: TextStyle(
            color: Colors.blueGrey,
            fontSize: 16.0,
            fontStyle: FontStyle.italic
          ),
          prefixIcon: Icon(Icons.person)
        ),
      validator: (v){
        return v.trim().length>0?null:"用户名不能为空";
      },
  );
 }

 Widget _fmPwdWidget(){
  return TextFormField(
      controller: _pwdCtrl, // 用于获取密码值
      obscureText: true,
      decoration: InputDecoration(
        labelText: "密码",
        hintText: "请输入密码",
        hintStyle: TextStyle(fontSize: 12.0,color: Colors.grey),
        labelStyle: TextStyle(
          color: Colors.blueGrey,
          fontSize: 16.0,
          fontStyle: FontStyle.italic
        ),
        prefixIcon: Icon(Icons.lock)
      ),
      validator: (v){
        return v.trim().length>3?null:"密码不能少于3位";
      },
  );
 }

 @override
 Widget build(BuildContext context) {

    return Scaffold(
      appBar: AppBar(title: Text("TextField"),),
      body: Form(
        key:_formKey,
        // autovalidate: true,
        child: Column(children: <Widget>[
        _fmUserNameWidget(),
        _fmPwdWidget(),
        RaisedButton(
          child: Text("登录"),
          onPressed: (){
            // 通过_formKey.currentState 获取FormState后,
            // 调用validate()方法校验用户名密码是否合法,校验
            // 通过后再提交数据。 
            if((_formKey.currentState as FormState).validate()){
              _setResult("成功$_count");
            }else{
              _setResult("失败");
            }
          },
        ),
        Text("${_fmResult==null?'':_fmResult}"),
      ],),
      )
    );
  }
  
}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值