写点什么

Flutter TextField 详解

作者:yechaoa
  • 2022 年 6 月 26 日
  • 本文字数:4880 字

    阅读完需:约 16 分钟

效果:



终于还是对TextField下手了,这个属性最多、功能点最多的 Widget。

基本属性

TextField是一个material design风格的输入框,本身有多种属性,除此之外装饰器InputDecoration也有多种属性,但都比较简单,所以不必担心,且听我娓娓道来。


先看一下源码,重要或常用的属性会有注释。

TextField

  const TextField({    Key key,    this.controller,//控制器    this.focusNode,//焦点    this.decoration = const InputDecoration(),//装饰    TextInputType keyboardType,//键盘类型,即输入类型    this.textInputAction,//键盘按钮    this.textCapitalization = TextCapitalization.none,//大小写    this.style,//样式    this.strutStyle,    this.textAlign = TextAlign.start,//对齐方式    this.textDirection,    this.autofocus = false,//自动聚焦    this.obscureText = false,//是否隐藏文本,即显示密码类型    this.autocorrect = true,//自动更正    this.maxLines = 1,//最多行数,高度与行数同步    this.minLines,//最小行数    this.expands = false,    this.maxLength,//最多输入数,有值后右下角就会有一个计数器    this.maxLengthEnforced = true,    this.onChanged,//输入改变回调    this.onEditingComplete,//输入完成时,配合TextInputAction.done使用    this.onSubmitted,//提交时,配合TextInputAction    this.inputFormatters,//输入校验    this.enabled,//是否可用    this.cursorWidth = 2.0,//光标宽度    this.cursorRadius,//光标圆角    this.cursorColor,//光标颜色    this.keyboardAppearance,    this.scrollPadding = const EdgeInsets.all(20.0),    this.dragStartBehavior = DragStartBehavior.start,    this.enableInteractiveSelection,    this.onTap,//点击事件    this.buildCounter,    this.scrollPhysics,  }) 
复制代码


参数很多,其实日常开发中连一半的属性都用不到,但还是会尽量多的介绍。

InputDecoration

  const InputDecoration({    this.icon,//左侧外的图标    this.labelText,//悬浮提示,可代替hintText    this.labelStyle,//悬浮提示文字的样式    this.helperText,//帮助文字    this.helperStyle,    this.hintText,//输入提示    this.hintStyle,    this.hintMaxLines,    this.errorText,//错误提示    this.errorStyle,    this.errorMaxLines,    this.hasFloatingPlaceholder = true,//是否显示悬浮提示文字    this.isDense,    this.contentPadding,//内填充    this.prefixIcon,//左侧内的图标    this.prefix,    this.prefixText,//左侧内的文字    this.prefixStyle,    this.suffixIcon,//右侧内图标    this.suffix,    this.suffixText,    this.suffixStyle,    this.counter,//自定义计数器    this.counterText,//计数文字    this.counterStyle,//计数样式    this.filled,//是否填充    this.fillColor,//填充颜色    this.errorBorder,    this.focusedBorder,    this.focusedErrorBorder,    this.disabledBorder,    this.enabledBorder,    this.border,//边框    this.enabled = true,    this.semanticCounterText,    this.alignLabelWithHint,  })
复制代码


参数很多,多为一个小功能点的图标、文字和样式,并不复杂。


ok,基本属性大概过一遍,脑子里有个印象就行了。下面开始实操。

样式

基础样式

      TextField(),
复制代码


很简单,无任何参数,当然效果也很简单。



style 可以修改样式。

隐藏文本

修改obscureText属性值


              TextField(                obscureText: true,              ),
复制代码



可以看到输入的内容已经不可见了,变成常见的密码类型了。

键盘类型

键盘类型 即 可输入的类型,比如number就只能输入数字


              TextField(                keyboardType: TextInputType.number,              ),
复制代码



TextInputType可选类型:


  • text

  • multiline

  • number

  • phone

  • datetime

  • emailAddress

  • url

键盘按钮

即键盘右下角的按钮,常见的比如完成,右下角是一个完成的对号按钮,上图即是。


              TextField(                textInputAction: TextInputAction.done,              ),
复制代码


TextInputAction其他选项:


  • none

  • unspecified

  • done

  • go

  • search

  • send

  • next

  • previous

  • continueAction

  • join

  • route

  • emergencyCall

  • newline

大小写

即控制输入的英文字母大小写,比如单词首字母大写


              TextField(                textCapitalization: TextCapitalization.words,              ),
复制代码



TextCapitalization的其他选项:


  • words:单词首字母大写

  • sentences:句子的首字母大写

  • characters:所有字母大写

  • none:默认无

光标

默认是一个蓝色的竖线


              TextField(                cursorColor: Colors.orange,                cursorWidth: 15,                cursorRadius: Radius.circular(15),              ),
复制代码


最多行数

设置最多 3 行


              TextField(                maxLines: 3,              ),
复制代码



从效果可以看出,TextField 高度已经变成了 3 行。但是我只是想最多输入 3 行,默认还是 1 行的高度怎么办呢?不用慌,加一个参数就行了: minLines


              TextField(                maxLines: 3,                minLines: 1,              ),
复制代码



可以看到,TextField 的高度是会自适应的。

计数器

即右下角会有一个计数


              TextField(                maxLength: 8,              ),
复制代码



默认:当前输入长度/最大长度,那这个地方我们能不能改呢,当然可以,下面简单操作一下


              TextField(                maxLength: 8,                decoration: InputDecoration(                  counter: Text("自定义计数 0/100"),                ),              ),
复制代码



这里我用到了装饰InputDecoration下的counter,类型是widget,那扩展度就相当高了,我只用了一个Text,别的 widget 也是可以的。


如果只是纯文字的话,InputDecoration 下还有一个counterText属性和counterStyle

图标

图标有 3 种:


  • 左侧外的图标


              TextField(                decoration: InputDecoration(                  icon: Icon(Icons.person),                ),              ),
复制代码



  • 左侧内图标


              TextField(                decoration: InputDecoration(                  prefixIcon: Icon(Icons.phone_android),                ),              ),
复制代码



  • 右侧内图标


              TextField(                decoration: InputDecoration(                  suffixIcon: IconButton(                    icon: Icon(Icons.close),                    onPressed: () {                      controller.clear();                    },                  ),                ),              ),
复制代码



在右侧图标加了一个IconButton,因为带有点击事件,我们可以在点击的时候清除 TextField 中的内容。


以上就是图标的介绍,其实除了图标之外,对应的位置也可以显示文字或者自定义显示其他 widget 比如出了prefixIcon之外还有其他 3 个属性,用法跟上面介绍到的自定义计数器是一样的。


    this.prefix,    this.prefixText,    this.prefixStyle,
复制代码

提示文字

提示文字有 4 种:


  • 输入提示文字


              TextField(                controller: controller,                decoration: InputDecoration(                  hintText: '请输入账号aaa',                ),              ),
复制代码



  • 悬浮提示文字


              TextField(                controller: controller,                decoration: InputDecoration(                  hintText: '请输入账号aaa',                  labelText: '请输入账号',                ),              ),
复制代码



可以看到,默认显示labelText,聚焦之后才显示hintText,所以 labelText 是可以取代 hintText 的。


  • 帮助提示文字


              TextField(                controller: controller,                decoration: InputDecoration(                  helperText: "帮助文字",                  helperStyle: TextStyle(color: Colors.blue)                ),              ),
复制代码



一直显示在左下方


  • 错误提示文字


              TextField(                controller: controller,                decoration: InputDecoration(                  errorText: "你没有输入任何内容",                ),              ),
复制代码


去除下划线

              TextField(                decoration: InputDecoration.collapsed(hintText: "无下划线的输入框"),              ),
复制代码



也可以decoration: null, 差别就是没有 hintText 了

边框

              TextField(                decoration: InputDecoration(                  border: OutlineInputBorder(),                ),              ),
复制代码



如果这个圆角不喜欢的话,也可以改一下的,比如:


              TextField(                decoration: InputDecoration(                  border: OutlineInputBorder(                    borderRadius: BorderRadius.all(Radius.circular(30)),                  ),                ),              ),
复制代码


获取输入内容

有两种方式:


  • onChangedonChanged是输入内容改变时的回调,返回一个String类型的数值,可以用一个变量记一下


              TextField(                onChanged: (text) {                  print("输入改变时" + text);                },              ),
复制代码


  • controller 即控制器,初始化:


  var controller;
@override void initState() { super.initState(); controller = TextEditingController(); controller.addListener(() {}); }
复制代码


配置给 TextField


              TextField(                controller: controller,              ),
复制代码


获取内容


controller.text
复制代码


在事件中调用controller.text即返回输入内容。

关闭软键盘

往往我们在事件中提交的时候,是需要关闭软键盘的


这里我们就用到了focusNode


初始化:


FocusNode userFocusNode = FocusNode();
复制代码


配置:


              TextField(                focusNode: userFocusNode,              ),
复制代码


然后在需要的地方调用:


userFocusNode.unfocus();
复制代码

校验

校验的话其实有个inputFormatters属性


  final List<TextInputFormatter> inputFormatters;
复制代码


继续看 TextInputFormatter 源码,有 3 个子类:


  • BlacklistingTextInputFormatter

  • WhitelistingTextInputFormatter

  • LengthLimitingTextInputFormatter


黑名单、白名单和长度限制,我们随便找一个看一下源码是怎么实现校验的:


往下看会看到这么一段代码:


  static final BlacklistingTextInputFormatter singleLineFormatter      = BlacklistingTextInputFormatter(RegExp(r'\n'));
复制代码


关键词在RegExp,其实就是我们一般用的正则表达式而已。


这样的话,我们也可以自定义校验规则了,比如校验手机号:


  String validateMobile(String value) {    String patttern = r'(^[0-9]*$)';    RegExp regExp = new RegExp(patttern);    if (value.length == 0) {      return "手机号为空";    } else if (!regExp.hasMatch(value)) {      return "手机号格式不正确";    }    return null;  }
复制代码


以上只是我们一般的校验,表单的话还是建议使用From包裹TextFormField

异常

  • 软键盘弹出之后遮盖

  • 软键盘弹出之后高度溢出


解决办法:用滑动组件包裹起来(ListView 等),这样软键盘弹出的时候,输入框也会自动向上滑。


<br>

总结

以上就是全部介绍了,然后写了个登录注册的小 demo:


github:https://github.com/yechaoa/wanandroid_flutter

官方文档:https://api.flutter.dev/flutter/material/TextField-class.html


<br>


写作不易,有用就随手点个赞或 star 呗


<br>

发布于: 刚刚阅读数: 3
用户头像

yechaoa

关注

优质作者 2018.10.23 加入

知名互联网大厂技术专家,多平台博客专家、优秀博主、人气作者,博客风格深入浅出,专注于Android领域,同时探索于大前端方向,持续研究并落地前端、小程序、Flutter、Kotlin等相关热门技术

评论

发布
暂无评论
Flutter TextField详解_flutter_yechaoa_InfoQ写作社区