Flutter--TextField学习

一、TextField学习

TextField 是文本输入组件,即输入框,常用组件之一

二、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.textAlignVertical,//垂直对齐方式
    this.textDirection,
    this.readOnly = false,//是否只能读取
    ToolbarOptions toolbarOptions,//配置工具栏
    this.showCursor,
    this.autofocus = false,//自动获取焦点
    this.obscuringCharacter = '•',
    this.obscureText = false,//是否隐藏文本,密码类型
    this.autocorrect = true,//自动更正
    SmartDashesType smartDashesType,
    SmartQuotesType smartQuotesType,
    this.enableSuggestions = true,
    this.maxLines = 1,//最大行数
    this.minLines,//最小行数
    this.expands = false,
    this.maxLength,//最多输入数,不为0时右下角有计数器
    this.maxLengthEnforced = true,
    this.onChanged,//输入改变回调
    this.onEditingComplete,//输入完成时,配合TextInputAction.done使用
    this.onSubmitted,//提交时,配合TextInputAction
    this.onAppPrivateCommand,
    this.inputFormatters,//输入校验
    this.enabled,//是否可用
    this.cursorWidth = 2.0,//光标宽度
    this.cursorHeight,//光标高度
    this.cursorRadius,//光标圆角
    this.cursorColor,//光标颜色
    this.selectionHeightStyle = ui.BoxHeightStyle.tight,
    this.selectionWidthStyle = ui.BoxWidthStyle.tight,
    this.keyboardAppearance,
    this.scrollPadding = const EdgeInsets.all(20.0),
    this.dragStartBehavior = DragStartBehavior.start,
    this.enableInteractiveSelection = true,
    this.onTap,//点击事件
    this.mouseCursor,
    this.buildCounter,
    this.scrollController,
    this.scrollPhysics,
    this.autofillHints,
    this.restorationId,
  }) : assert(textAlign != null),
       assert(readOnly != null),
       assert(autofocus != null),
       assert(obscuringCharacter != null && obscuringCharacter.length == 1),
       assert(obscureText != null),
       assert(autocorrect != null),
       smartDashesType = smartDashesType ?? (obscureText ? SmartDashesType.disabled : SmartDashesType.enabled),
       smartQuotesType = smartQuotesType ?? (obscureText ? SmartQuotesType.disabled : SmartQuotesType.enabled),
       assert(enableSuggestions != null),
       assert(enableInteractiveSelection != null),
       assert(maxLengthEnforced != null),
       assert(scrollPadding != null),
       assert(dragStartBehavior != null),
       assert(selectionHeightStyle != null),
       assert(selectionWidthStyle != 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(!obscureText || maxLines == 1, 'Obscured fields cannot be multiline.'),
       assert(maxLength == null || maxLength == TextField.noMaxLength || maxLength > 0),
       // Assert the following instead of setting it directly to avoid surprising the user by silently changing the value they set.
       assert(!identical(textInputAction, TextInputAction.newline) ||
         maxLines == 1 ||
         !identical(keyboardType, TextInputType.text),
         'Use keyboardType TextInputType.multiline when using TextInputAction.newline on a multiline TextField.'),
       keyboardType = keyboardType ?? (maxLines == 1 ? TextInputType.text : TextInputType.multiline),
       toolbarOptions = toolbarOptions ?? (obscureText ?
         const ToolbarOptions(
           selectAll: true,
           paste: true,
         ) :
         const ToolbarOptions(
           copy: true,
           cut: true,
           selectAll: true,
           paste: true,
         )),
       super(key: key);

三、TextField属性说明

属性 说明
controller 控制器
为绑定的输入框 TextField 预设内容,TextEditingController(text:"初始化")
获取输入框内容,textEditingController.text
清空输入框内容,textEditingController.text ="",textEditingController.clear()
focusNode 焦点,用来控制TextField 焦点的获取与关闭,获取焦点FocusScope.of(context).requestFocus(focusNode),失去焦点,focusNode.unfocus()
decoration 装饰,InputDecoration详细见下文
keyboardType 键盘类型,输入类型
text:通用键盘
multiline:当TextField为多行时(maxLines设置大于1),右下角的为“换行” 按键。
number:数字键盘
phone:手机键盘,比数字键盘多"*"和 "#"
datetime:在ios上和text一样,在android上出现数字键盘、":"和 "-"
emailAddress:邮箱键盘,有"@" 和 "."按键
url:url键盘,有"/" 和 "."按键
visiblePassword:既有字幕又有数字的键盘
textInputAction 键盘右下角按钮(Android上显示的按钮大部分是不确定的)
none:android上显示返回键,ios不支持。
unspecified:让操作系统自己决定哪个合适,一般情况下,android显示“完成”或者“返回”。
done:android显示代表“完成”的按钮,ios显示“Done”(中文:完成)。
go:android显示表达用户去向目的地的图标,比如向右的箭头,ios显示“Go”(中文:前往)。
search:android显示表达搜索的按钮,ios显示"Search"(中文:搜索)。
send:android显示表达发送意思的按钮,比如“纸飞机”按钮,ios显示"Send"(中文:发送)。
next:android显示表达“前进”的按钮,比如“向右的箭头”,ios显示"Next"(中文:下一项)。
previous:android显示表达“后退”的按钮,比如“向左的箭头”,ios不支持。
continueAction:android 不支持,ios仅在ios9.0+显示"Continue"(中文:继续)。
join:Android和ios显示"Join"(中文:加入)。
route:android 不支持,ios显示"Route"(中文:路线)。
emergencyCall:android 不支持,ios显示"Emergency Call"(中文:紧急电话)。
newline:android显示表达“换行”的按钮,ios显示”换行“。
textCapitalization 大小写,仅仅是控制软键盘是大写模式还是小写模式,你也可以切换大小写
words:每一个单词的首字母大写。
sentences:每一句话的首字母大写。
characters:每个字母都大写
none:都小写
style 样式
textAlign 水平对齐方式
textAlignVertical 垂直对齐方式
readOnly 是否只能读,不可输入
toolbarOptions 长按时弹出的菜单,有copy、cut、paste、selectAll四个选项可配置
autofocus 是否自动获取焦点
obscuringCharacter 密码模式下显示文本
obscureText 是否隐藏文本,密码模式
autocorrect 自动更正
maxLines 最大行数
minLines /最小行数
maxLength 最多输入数,不为0时右下角有计数器
onChanged 输入改变回调
onEditingComplete 输入完成时,配合TextInputAction.done使用
onSubmitted 提交时,配合TextInputAction
inputFormatters 输入校验,限制用户输入的内容
enabled 是否可用
cursorWidth 光标宽度
cursorHeight 光标高度
cursorRadius 光标圆角
cursorColor 光标颜色
showCursor 是否显示光标
onTap 点击事件

四、InputDecoration的源码

const InputDecoration({
    this.icon,//位于装饰器外部和输入框前面的图片
    this.labelText,//用于描述输入框
    this.labelStyle,// 控制labelText的样式
    this.helperText,//帮助文本
    this.helperStyle,//helperText的样式
    this.helperMaxLines,//帮助文本的最大行数
    this.hintText,//提示文本
    this.hintStyle,//hintText的样式
    this.hintMaxLines,//提示文本的最大行数
    this.errorText,//错误文本
    this.errorStyle,//errorText的样式
    this.errorMaxLines,//错误文本的最大行数
    @Deprecated(
      'Use floatingLabelBehavior instead. '
      'This feature was deprecated after v1.13.2.'
    )
    this.hasFloatingPlaceholder = true,//labelText是否浮动
    this.floatingLabelBehavior = FloatingLabelBehavior.auto,//浮动标签应该如何显示
    this.isCollapsed = false,//是否可折叠
    this.isDense,//改变输入框是否为密集型
    this.contentPadding,//内间距
    this.prefixIcon,//位于输入框内部起始位置的图标。
    this.prefixIconConstraints,//设置起始位置图片的大小
    this.prefix,//预先填充的Widget
    this.prefixText,//预填充的文本
    this.prefixStyle, //prefixText的样式
    this.suffixIcon,//位于输入框后面的图片
    this.suffix,//位于输入框尾部的控件
    this.suffixText,//位于尾部的填充文字
    this.suffixStyle, //suffixText的样式
    this.suffixIconConstraints,//设置输入框后面图片的大小
    this.counter,//位于输入框右下方的小控件
    this.counterText,//位于右下方显示的文本
    this.counterStyle,//counterText的样式
    this.filled,  //如果为true,则输入使用fillColor指定的颜色填充
    this.fillColor,//相当于输入框的背景颜色
    this.focusColor,//获取焦点时颜色
    this.hoverColor,
    this.errorBorder, //errorText不为空,输入框没有焦点时要显示的边框
    this.focusedBorder,//输入框有焦点时的边框
    this.focusedErrorBorder,//输入框有焦点时的边框
    this.disabledBorder,//输入框禁用时显示的边框
    this.enabledBorder,//输入框可用时显示的边框
    this.border,//正常情况下的边框
    this.enabled = true,//输入框是否可用
    this.semanticCounterText,
    this.alignLabelWithHint,
  }) : 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.');

五、InputDecoration的属性介绍

属性 说明
icon 位于装饰器外部和输入框前面的图片
labelText 用于描述输入框
labelStyle 控制labelText的样式,TextStyle类型
helperText 帮助文本
helperStyle helperText的样式,TextStyle类型
helperMaxLines 帮助文本的最大行数
hintText 提示文本
如果有设置labelText,输入框获取焦点,才能显示hintText
hintMaxLines 提示文本的最大行数
errorText 错误文本
如果同时设置errorText和helperText,那么helperText会隐藏
errorStyle errorText的样式,TextStyle类型
floatingLabelBehavior:FloatingLabelBehavior.auto时,且输入框获取焦点时,errorStyle设置颜色会覆盖labelText的颜色
如果同时设置errorStyle和helperStyle,helperStyle样式会隐藏
errorMaxLines 错误文本的最大行数
hasFloatingPlaceholder labelText是否浮动,bool类型(已弃用)
值为true,输入框获取焦点labelText会浮动到输入框顶部
值为false,输入框获取焦点,labelText会隐藏
floatingLabelBehavior 浮动标签应该如何显示
FloatingLabelBehavior.never:labelText显示在输入框内,不可浮动
FloatingLabelBehavior.auto:labelText可浮动
FloatingLabelBehavior.always:labelText一直浮动在输入框上部
isCollapsed 是否可折叠
isDense 改变输入框是否为密集型,主要约束前置和后置图标的BoxConstraints大小
contentPadding 内间距
prefixIcon 位于输入框内部起始位置的图标。
prefixIconConstraints 设置起始位置图片的大小
prefix 预先填充的Widget,和prefixText只能同时存在一个
prefixText 预填充的文本,和prefix只能同时存在一个
prefixStyle prefixText的样式
suffixIcon 位于输入框后面的图片
suffix 位于输入框尾部的控件,和suffixText只能同时存在一个
suffixText 位于尾部的填充文字,和suffix只能同时存在一个
suffixStyle suffixText的样式
suffixIconConstraints 设置输入框后面图片的大小
counter 位于输入框右下方的小控件,不能和counterText同时使用
counterText 位于右下方显示的文本,不能和counter同时使用
counterStyle counterText的样式
filled 如果为true,则输入使用fillColor指定的颜色填充
fillColor 相当于输入框的背景颜色
focusColor 获取焦点时颜色
hoverColor 和鼠标有关
errorBorder errorText不为空,输入框没有焦点时要显示的边框
focusedBorder 输入框有焦点时的边框
focusedErrorBorder errorText不为空,输入框有焦点时的边框
disabledBorder 输入框禁用时显示的边框
enabledBorder 输入框可用时显示的边框
border 正常情况下的边框
enabled 输入框是否可用
border的优先级
  1. 控件禁用时
    当enabled为false时,如果指定了disabledBorder,优先使用disabledBorder,没有的话设置disabledBorder则使用border的部分样式(颜色默认是灰色)
  2. 控件启用(enable为true),但errorText有值
    输入框没有焦点时,优先使用errorBorder的样式,输入框有焦点时,优先使用focusedErrorBorder,如果这两个都没有设置则使用border的部分样式(颜色默认是红色)
  3. 控件启用状态,且errorText没有值
    输入框没有焦点时,优先使用enabledBorder ,有焦点时,优先使用focusedBorder,两者均没有指定时,使用默认的border

六、TextField、InputDecoration的demo

6.1、InputDecoration的使用
return MaterialApp(
      home: Scaffold(
          appBar: AppBar(
            title: Text("TextField学习"),
          ),
          body: Container(
            padding: EdgeInsets.all(15),
            child: TextField(
                decoration: InputDecoration(
                  icon: Icon(Icons.person,size: 35,color: Colors.blue,),
                  labelText: "我是labelText",
                  labelStyle: TextStyle(
                    fontSize: 15
                  ),
                  helperText: "我是helperText",
                  helperStyle: TextStyle(
                    color: Colors.orange
                  ),
                  helperMaxLines: 2,
                  hintText: "我是hintText我是hintText我是hintText我是hintText我是hintText我是hintText我是hintText我是hintText我是hintText我是hintText",
                  hintMaxLines: 1,
                  errorText: "我是errorText",
                  errorStyle: TextStyle(
                    color: Colors.purpleAccent,
                    fontSize: 12
                  ),
                  //labelText是否会浮动
                  hasFloatingPlaceholder: true,
                  //labelText浮动的如何显示
                  floatingLabelBehavior:FloatingLabelBehavior.always,
                  //是否为密集型
                  isDense: false,
                  //内间距
                  contentPadding:EdgeInsets.fromLTRB(5, 0, 5, 0),
                  //位于输入框内部起始位置的图标
                  prefixIcon: Icon(Icons.search),
                    //设置起始位置图片的大小
                  prefixIconConstraints: BoxConstraints(minHeight: 5),
                  //预填充的widget
//                  prefix: Container(height: 10,width: 10,color: Colors.red,),
                    //预填充的文本
                  prefixText: "+86",
                    //位于输入框后面的图片
                  suffixIcon: Icon(Icons.cleaning_services),
                  //控制输入框后面的图片的大小
                    suffixIconConstraints:BoxConstraints(minHeight: 5),
                  //位于右下方显示的组件
//                  counter: Text("0/10"),
                  //位于右下方显示的文本
                  counterText: "0/10",
                  //是否使用fillColor颜色为输入框背景色
                  filled: true,
                  //输入框背景色
                  fillColor: Colors.white,
                  //有errorText,未获取焦点边框
                  errorBorder: OutlineInputBorder(
                      /*边角*/
                      borderRadius: BorderRadius.all(
                        Radius.circular(5), //边角为30
                      ),
                      borderSide: BorderSide(
                        color: Colors.yellow,
                        width: 1
                      )
                  ),
                  //有errorText,获取焦点边框
                  focusedErrorBorder: OutlineInputBorder(
                    /*边角*/
                      borderRadius: BorderRadius.all(
                        Radius.circular(5), //边角为30
                      ),
                      borderSide: BorderSide(
                          color: Colors.blue,
                          width: 1
                      )
                  ),
                ),
            ),
          )),
    );
e57566e83b1925f3f7194041e6c6299.png
6.2、TextField设置内容,并且保持光标在末尾
void main() {
  runApp(TextFieldFul());
}


class TextFieldFul extends StatefulWidget {
  TextFieldFul({Key key}) : super(key: key);

  _TextFieldFulState createState() => _TextFieldFulState();
}

class _TextFieldFulState extends State {
  var textEditingController = TextEditingController();

  @override
  void initState() {
    super.initState();
    //初始化输入框的内容
    String initStr = "ysl";
    //初始化光标在文本的后面
    textEditingController = TextEditingController.fromValue(
      //初始化文本的显示
        TextEditingValue(
          //设置初始化文本
          text:initStr,
          //设置光标的位置
          selection: TextSelection.fromPosition(
            //设置文本的位置
            TextPosition(
              affinity: TextAffinity.downstream,
                //光标向后移动的位置
                offset:initStr.length
            )
          )
        )

    );
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
          appBar: AppBar(
            title: Text("TextField学习"),
          ),
          body: Container(
            padding: EdgeInsets.all(15),
            child: TextField(
              controller: textEditingController,
              onChanged: (value){
                print(textEditingController.text);
              },
              autofocus: true,
            ),
          )),
    );
  }
}
6.3、TextField焦点获取和失去
class _TextFieldFulState extends State {
  //焦点组件
  FocusNode focusNode = FocusNode();

  @override
  void initState() {
    super.initState();

    focusNode.addListener(() {
      //是否获取焦点
      bool hasFocus = focusNode.hasFocus;
      //是否添加了监听
      bool hasListener = focusNode.hasListeners;

      print("ysl--hasFocus:${hasFocus},hasListener:${hasListener}");
    });
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
          appBar: AppBar(
            title: Text("TextField学习"),
          ),
          body: Container(
            padding: EdgeInsets.all(15),
            child: Column(
              children: [
                TextField(
                  autofocus: true,
                  focusNode: focusNode,
                ),
                SizedBox(
                  height: 15,
                ),
                Row(
                  mainAxisAlignment: MainAxisAlignment.spaceAround,
                  children: [
                    OutlinedButton(child: Text("获取焦点"), onPressed: () {
                      FocusScope.of(context).requestFocus(focusNode);
                    }),
                    OutlinedButton(child: Text("失去焦点"), onPressed: () {
                      focusNode.unfocus();
                    })
                  ],
                )
              ],
            ),
          )),
    );
  }
}
09c0705afa19d880495b6fbee0aecac.png
6.4、TextField的简单使用
return MaterialApp(
      home: Scaffold(
          appBar: AppBar(
            title: Text("TextField学习"),
          ),
          body: Container(
            padding: EdgeInsets.all(10),
            child: TextField(
              //键盘类型
              keyboardType: TextInputType.phone,
              //键盘右下角按钮
              textInputAction: TextInputAction.none,
              //大小写
              textCapitalization: TextCapitalization.words,
              //样式
              style: TextStyle(
                color: Colors.red
              ),
              //水平对齐方式
              textAlign: TextAlign.center,
              //垂直对齐方式
              textAlignVertical: TextAlignVertical.center,
              //是否只读
              readOnly: false,
              //长按时弹出的菜单
              toolbarOptions:ToolbarOptions(
                copy: true,
                cut: true,
                paste: true,
                selectAll: true
              ) ,
              //是否自动获取焦点
              autofocus: false,
              //密码模式
              obscureText: true,
              //密码模式下显示文本
              obscuringCharacter: "*",
              //光标宽度
              cursorWidth: 5,
              cursorHeight: 10,
              //是否显示光标
              showCursor: true,
              //最多输入数量
              maxLength: 11,
              onTap: (){
                print("点击了输入框");
              },


            ),
          )),
    );
54e6d941e262066dfecb580fc8a1d52.png

你可能感兴趣的:(Flutter--TextField学习)