Flutter 学习 - Widget 之 TextField

前言

本章介绍Flutter中文本输入框Widget - TextField
,在实际项目中输入框可谓是不可缺少的,无论是注册登录还是意见反馈,直至到评论这些很常见到功能都需要用户进行输入操作,那Flutter中如何使用TextField进行文本输入呢,下面我们来介绍下。

使用方式

最简单的使用方式:

TextField()

效果如下:


TextField运行效果.gif

源码分析

下面我们看下TextFiled的源码

const TextField({
    Key key,//Widget的标识
    this.controller,//控制TextField的编辑,不设置会有默认值,类型是TextEditingController
    this.focusNode,//用于控制TextField是否有当前键盘的输入焦点,类型是FocusNode
    this.decoration = const InputDecoration(),//用于控制TextField的外观显示,如颜色,边框等,类型是InputDecoration
    TextInputType keyboardType,//用于设置该输入框默认的键盘输入类型,类型是TextInputType
    this.textInputAction,//键盘动作按钮图标(即回车键位图标),类型是TextInputAction
    this.textCapitalization = TextCapitalization.none,//定义文本的大写格式,类型是TextCapitalization
    this.style,//文本样式,类型是TextStyle
    this.strutStyle,//使用的支柱风格,类型是StrutStyle
    this.textAlign = TextAlign.start,//文本的对齐方式,类型是TextAlign
    this.textAlignVertical,//垂直对齐,类型是TextAlignVertical
    this.textDirection,//文字方向,类型TextDirection
    this.readOnly = false,//bool类型,文本是不是不能编辑
    this.showCursor,//bool类型,是否显示光标
    this.autofocus = false,//类型是bool,是否自动获取焦点
    this.obscureText = false,//类型是bool,是否隐藏正在编辑的文本,用于密文等,文本内容会用“•”替换,默认为false
    this.autocorrect = true,//类型是bool,是否自动更正
    this.maxLines = 1,//类型是int,显示的最大行数
    this.minLines,//类型是int,最小展示行数
    this.expands = false,//bool 类型,是否可扩展
    this.maxLength,//类型是int,输入框中允许的最大字数
    /**
    *  类型是bool,是否强制限制最大字符数,默认为true
    *  true:强制限制最大字符数
    *  false:不限制最大字符数,即使设置了maxLength也不生效
    **/
    this.maxLengthEnforced = true,
    this.onChanged,//输入框内容改变时的回调函数,类型是ValueChanged
    this.onEditingComplete,//输入框输入完成时触发,但是onEditingComplete没有参数,不会返回内容,类型是VoidCallback
    this.onSubmitted,//输入框输入完成时触发,但是onSubmitted有参数,会返回内容,类型是ValueChanged
    this.inputFormatters,//用于指定输入格式;当用户输入内容改变时,会根据指定的格式来校验。类型是List< TextInputFormatter>
    /**
    *  类型是bool,输入框是否禁用,如果为false,则输入框会被禁用
    *    ,禁用状态不接收输入和事件,同时* *   显示禁用态样式(在其    
    *   decoration中定义)。
      **/
    this.enabled,
    this.cursorWidth = 2.0,//类型是double,自定义输入框光标宽度
    this.cursorRadius,//自定义输入框光标圆角,类型是Radius
    this.cursorColor,//自定义光标颜色,类型是Color
    this.keyboardAppearance,//设置键盘的外观模式,只能在iOS上使用,类型是Brightness
    this.scrollPadding = const EdgeInsets.all(20.0),//文本框滑动时的间距,类型是EdgeInsets
    this.dragStartBehavior = DragStartBehavior.start,//设置设置决定了用户何时正式启动拖动,类型是DragStartBehavior
    this.enableInteractiveSelection,//类型是bool 是否启用交互式选择,true:长按将会选中文字,并且弹出 cut/copy/paste 的菜单
    this.onTap,//TextField的点击事件,类型是GestureTapCallback
    this.buildCounter,//生成自定义 InputDecorator.counter 小部件的回调,类型是InputCounterWidgetBuilder
    this.scrollController,//类型是ScrollController,滚动监听器
    this.scrollPhysics,//类型是 ScrollPhysics,确定滚动的物理属性
  }) : assert(textAlign != null),
       assert(readOnly != null),
       assert(autofocus != null),
       assert(obscureText != null),
       assert(autocorrect != null),
       assert(maxLengthEnforced != null),
       assert(scrollPadding != null),
       assert(dragStartBehavior != null),
       assert(maxLines == null || maxLines > 0),
       assert(minLines == null || minLines > 0),
       assert(
         (maxLines == null) || (minLines == null) || (maxLines >= minLines),
         'minLines can\'t be greater than maxLines',
       ),
       assert(expands != null),
       assert(
         !expands || (maxLines == null && minLines == null),
         'minLines and maxLines must be null when expands is true.',
       ),
       assert(maxLength == null || maxLength == TextField.noMaxLength || maxLength > 0),
       keyboardType = keyboardType ?? (maxLines == 1 ? TextInputType.text : TextInputType.multiline),
       super(key: key);

注:TextField中的参数都是可选的

下面看下TextField中获取输入内容的两种方法

  • TextEditingController

TextEditingController是TextField的控制类,可以控制Textfield的编辑,是TextField的controller属性,我们可以给TextField赋值自己创建的TextEditingController对象来控制TextField,使用方式如下:

class _MyHomePageState extends State<MyHomePage> {
  TextEditingController _controller = TextEditingController();
  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: Text(
            widget.title,
            textWidthBasis: TextWidthBasis.parent,
          ),
        ),
        body: TextField(
          controller: _controller,
        ));
  }
}

然后我们就可以用_controller.text来访问TextField里的内容了。

  • ValueChanged

当用户输入,TextField的内容发生变化,TextField就会回调它的onChanged回调。因此onChanged可以实时查看TextField的内容变化
使用方法:

onChanged: (String data){
      //实时获取
      print(data);
 },
  • FocusNode
    使用方式
FocusNode()

源码分析

 FocusNode({
    String debugLabel,//String类型,设置debug标签,这样不会影响release环境
    FocusOnKeyCallback onKey,//获取焦点回调,类型是FocusOnKeyCallback
    this.skipTraversal = false,//bool类型是否跳过焦点遍历事件,默认为false
  })  : assert(skipTraversal != null),
        _onKey = onKey {
    // Set it via the setter so that it does nothing on release builds.
    this.debugLabel = debugLabel;
  }
  • InputDecoration
const InputDecoration({
    this.icon,//图片,类型是Widget
    this.labelText,//String 类型,描述输入字段的文本
    this.labelStyle,//lableText样式,类型是TextStyle
    this.helperText,//String 提供有关输入的提示文本,比如改如何使用
    this.helperStyle,//helperText的样式,类型是TextStyle
    this.hintText,//String类型,指示字段接受何种类型的输入
    this.hintStyle,//hintText的样式,类型是TextStyle
    this.hintMaxLines,//int 类型,[hintText]所能占用的最大行数。
    this.errorText,//String类型,出现在输入边框下方的错误提示文本。
    this.errorStyle,//errorText的样式,类型是TextStyle
    this.errorMaxLines,//int 类型,errorMaxLines所能占用的最大行数。
    this.hasFloatingPlaceholder = true,//bool类型,标签是否在焦点上浮动
    this.isDense,//bool 类型,输入是否为密集形式(即使用较少的垂直空间)。
    this.contentPadding,//输入内容的那边距,类型是EdgeInsetsGeometry
    this.prefixIcon,//出现在前缀或装饰器文本字段的可编辑部分之前的图标,类型为Widget
    this.prefix,//可选小部件放置在输入之前的行上,类型为Widget
    this.prefixText,//String 类型可选文本前缀,放在输入之前的行上
    this.prefixStyle,//prefixText的样式,类型为TextStyle
    this.suffixIcon,//出现在文本可编辑部分后,或者装饰容中文本的后缀上,类型是Widget
    this.suffix,//可选小部件,可放置在输入后的行上。类型是Widget
    this.suffixText,//String类型,可选文本后缀,放在输入后的行上。
    this.suffixStyle,//suffixText的样式,类型为TextStyle
    this.counter,//可选的自定义计数器小部件,类型是Widget
    this.counterText,//String类型,可选文本放在行下作为字符计数。
    this.counterStyle,//counterText的样式,类型TextStyle
    this.filled,//bool类型,装饰的容器将填满
    this.fillColor,//填充颜色,类型是 Color
    this.focusColor,//与[fillColor]混合并填充装饰容器的颜色,类型是 Color
    this.hoverColor,//如果容器被鼠标悬停在上面,则显示用于装饰的焦点突出显示的颜色。类型是 Color
    this.errorBorder,//当[InputDecorator]没有焦点并且显示错误时要显示的边框。类型 InputBorder
    this.focusedBorder,//当[InputDecorator]有焦点且没有显示错误时要显示的边框。类型 InputBorder
    this.focusedErrorBorder,//当[InputDecorator]具有焦点并显示错误时要显示的边框。类型 InputBorder
    this.disabledBorder,//当[InputDecorator]被禁用并且没有显示错误时显示的边框。类型 InputBorder
    this.enabledBorder,//启用[InputDecorator]时要显示的边框,并且没有显示错误。类型 InputBorder
    this.border,//边框的形状,以画出周围装饰的容器。类型 InputBorder
    this.enabled = true,//bool 类型,如果为false, [helperText]、[errorText]和[counterText]则不展示,其余可视元素的不透明度减少。
    this.semanticCounterText,//String类型,对应文本的语义标签。
    this.alignLabelWithHint,//bool 类型,当[InputDecorator]包含多行时,通常设置为true
  }) : assert(enabled != null),
       assert(!(prefix != null && prefixText != null), 'Declaring both prefix and prefixText is not supported.'),
       assert(!(suffix != null && suffixText != null), 'Declaring both suffix and suffixText is not supported.'),
       isCollapsed = false;
  • TextInputType
TextInputType的值 含义
TextInputType.text 文本输入键盘
TextInputType.multiline 多行文本,需和maxLines配合使用(设为null或大于1)
TextInputType.number 数字;会弹出数字键盘
TextInputType.phone 优化后的电话号码输入键盘;会弹出数字键盘并显示"* #"
TextInputType.datetime 优化后的日期输入键盘;Android上会显示“: -”
TextInputType.emailAddress 优化后的电子邮件地址;会显示“@ .”
TextInputType.url 优化后的url输入键盘; 会显示“/ .”
  • TextInputAction

类型为TextInputAction,键盘动作按钮图标(即回车键位图标)。
就是键盘右下角的那一个块图标。

使用方式

TextField(
   textInputAction: TextInputAction.search,
 ))

效果如下


TextInputAction的值 含义 示例
TextInputAction.none Android适用,IOS不适用,表示没有相关的输入操作
TextInputAction.unspecified 让系统决定哪个最合适
TextInputAction.done 用户完成输入后,终结该行为
TextInputAction.go 将用户带到程序中与目的地对应的部分,如用户输入一个餐馆名称,点击后可进行导航或者展示目的地位置
TextInputAction.search 执行搜索查询
20190803210756.jpg
TextInputAction.send 发送用户已编写的内容,如短信或邮件
TextInputAction.next 用户已经完成当前的输入源,转向下一个
TextInputAction.previous Android上适用,一个向左的箭头,表示向后移动,iOS不适用
TextInputAction.continueAction iOS上使用,Android上不适用,表示继续操作
TextInputAction.join 用户想要加入一些东西,如无线网络
TextInputAction.route 用户需要路由选项,如驾驶方向
TextInputAction.emergencyCall 拨打紧急服务电话
TextInputAction.newline 插入换行符
  • TextCapitalization
TextCapitalization的值 含义
TextCapitalization.none 全部小写
TextCapitalization.words 每个单词的首字母大写
TextCapitalization.sentences 每个句子的首字母大写
TextCapitalization.characters 每个字每大写
  • Brightness
Brightness的值 含义
Brightness.dark 深色主题
Brightness.light 浅色主题
  • DragStartBehavior
DragStartBehavior的值 含义
DragStartBehavior.down 在检测到第一个down事件的位置设置初始偏移量。
DragStartBehavior.start 将初始位置设置为检测到拖动启动事件的位置。

结尾

截止到这里TextField就介绍完了。
以下是我的Flutter系列的链接,后续会持续更新,欢迎大家指正。

Flutter 系列文章

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,294评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,780评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,001评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,593评论 1 289
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,687评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,679评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,667评论 3 415
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,426评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,872评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,180评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,346评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,019评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,658评论 3 323
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,268评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,495评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,275评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,207评论 2 352

推荐阅读更多精彩内容