说明

TextField 组件就是用来做文本输入的组件。

常用属性

TextField({
    Key key,
    this.controller, //编辑框的控制器,跟文本框的交互一般都通过该属性完成,如果不创建的话默认会自动创建
    this.focusNode, //用于管理焦点
    this.decoration = const InputDecoration(), //输入框的装饰器,用来修改外观
    TextInputType keyboardType, //设置输入类型,不同的输入类型键盘不一样
    this.textInputAction, //用于控制键盘动作(一般位于右下角,默认是完成)
    this.textCapitalization = TextCapitalization.none,
    this.style, //输入的文本样式
    this.textAlign = TextAlign.start, //输入的文本位置
    this.textDirection, //输入的文字排列方向,一般不会修改这个属性
    this.autofocus = false, //是否自动获取焦点
    this.obscureText = false, //是否隐藏输入的文字,一般用在密码输入框中
    this.autocorrect = true, //是否自动校验
    this.maxLines = 1, //最大行
    this.maxLength, //能输入的最大字符个数
    this.maxLengthEnforced = true, //配合maxLength一起使用,在达到最大长度时是否阻止输入
    this.onChanged, //输入文本发生变化时的回调
    this.onEditingComplete, //点击键盘完成按钮时触发的回调,该回调没有参数,(){}
    this.onSubmitted, //同样是点击键盘完成按钮时触发的回调,该回调有参数,参数即为当前输入框中的值。(String){}
    this.inputFormatters, //对输入文本的校验
    this.enabled, //输入框是否可用
    this.cursorWidth = 2.0, //光标的宽度
    this.cursorRadius, //光标的圆角
    this.cursorColor, //光标的颜色
    this.keyboardAppearance,
    this.scrollPadding = const EdgeInsets.all(20.0),
    this.dragStartBehavior = DragStartBehavior.down,
    this.enableInteractiveSelection,
    this.onTap, //点击输入框时的回调(){}
    this.buildCounter,
  })

decoration属性

接收InputDecoration类型的值,主要用于控制TextField的外观以及提示信息等

InputDecoration({
    this.icon, //位于装饰器外部和输入框前面的图片
    this.labelText, //用于描述输入框,例如这个输入框是用来输入用户名还是密码的,当输入框获取焦点时默认会浮动到上方,
    this.labelStyle, // 控制labelText的样式,接收一个TextStyle类型的值
    this.helperText, //辅助文本,位于输入框下方,如果errorText不为空的话,则helperText不会显示
    this.helperStyle, //helperText的样式
    this.hintText, //提示文本,位于输入框内部
    this.hintStyle, //hintText的样式
    this.hintMaxLines, //提示信息最大行数
    this.errorText, //错误信息提示
    this.errorStyle, //errorText的样式
    this.errorMaxLines, //errorText最大行数
    this.hasFloatingPlaceholder = true, //labelText是否浮动,默认为true,修改为false则labelText在输入框获取焦点时不会浮动且不显示
    this.isDense, //改变输入框是否为密集型,默认为false,修改为true时,图标及间距会变小
    this.contentPadding, //内间距
    this.prefixIcon, //位于输入框内部起始位置的图标。
    this.prefix, //预先填充的Widget,跟prefixText同时只能出现一个
    this.prefixText, //预填充的文本,例如手机号前面预先加上区号等
    this.prefixStyle, //prefixText的样式
    this.suffixIcon, //位于输入框后面的图片,例如一般输入框后面会有个眼睛,控制输入内容是否明文
    this.suffix, //位于输入框尾部的控件,同样的不能和suffixText同时使用
    this.suffixText,//位于尾部的填充文字
    this.suffixStyle, //suffixText的样式
    this.counter,//位于输入框右下方的小控件,不能和counterText同时使用
    this.counterText,//位于右下方显示的文本,常用于显示输入的字符数量
    this.counterStyle, //counterText的样式
    this.filled, //如果为true,则输入使用fillColor指定的颜色填充
    this.fillColor, //相当于输入框的背景颜色
    this.errorBorder, //errorText不为空,输入框没有焦点时要显示的边框
    this.focusedBorder, //输入框有焦点时的边框,如果errorText不为空的话,该属性无效
    this.focusedErrorBorder, //errorText不为空时,输入框有焦点时的边框
    this.disabledBorder, //输入框禁用时显示的边框,如果errorText不为空的话,该属性无效
    this.enabledBorder, //输入框可用时显示的边框,如果errorText不为空的话,该属性无效
    this.border, //正常情况下的border
    this.enabled = true, //输入框是否可用
    this.semanticCounterText,
    this.alignLabelWithHint,
  })

controller属性

 controller是输入框文本编辑的控制器,可以获取TextField的内容、设置 TextField的内容。

keyboardType属性

keyboardType参数控制软键盘的类型:

  • text:
    通用键盘。
  • multiline:
    当TextField为多行时(maxLines设置大于1),右下角的为“换行” 按键。
  • number:
    数字键盘。
  • phone:
    手机键盘,比数字键盘多"*"和 "#"。
  • datetime:
    在ios上和text一样,在android上出现数字键盘、":"和 "-"。
  • emailAddress:
    邮箱键盘,有"@" 和 "."按键。
  • url:
    url键盘,有"/" 和 "."按键。
  • visiblePassword:
    既有字幕又有数字的键盘。

textInputAction属性

textInputAction参数控制软键盘右下角的按键,说明如下:

  • 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显示”换行“。

注:Android上显示的按钮大部分是不确定的,比如next有的显示向右的箭头,有的显示前进,这是因为各大厂商对Android ROM定制引发的。

textCapitalization属性

textCapitalization参数是配置键盘是大写还是小写,仅支持键盘模式为text,其他模式下忽略此配置,说明如下:

  • words:
    每一个单词的首字母大写。
  • sentences:
    每一句话的首字母大写。
  • characters:
    每个字母都大写
  • none:
    都小写

动态焦点的获取:

FocusScope.of(context).requestFocus(_focusNode);
_focusNode = FocusNode();

TextField(
  focusNode: _focusNode,
  ...
)

失去焦点:

_focusNode.unfocus();

说明:CupertinoTextField和TextField基本一样,TextField是基于Material风格的,而CupertinoTextField是ios风格的输入框。

示例代码

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';

import 'cut_corners_border.dart';

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

  _TextFieldPageState createState() => _TextFieldPageState();
}

class _TextFieldPageState extends State<TextFieldPage> {
  String name = "张三";
  final TextEditingController controller = TextEditingController();
  final TextEditingController _phoneNumController = TextEditingController();
  final TextEditingController _pwdController = TextEditingController();
  final FocusNode _focusNode = FocusNode();

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

    controller.addListener(() {
      print("你输入的内容:${controller.text}");
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: Text(
            'TextField',
            style: TextStyle(fontSize: 18, fontWeight: FontWeight.w600),
          ),
          centerTitle: true,
          elevation: 0.0,
        ),
        body: ListView(
          children: [
            Padding(
              padding: EdgeInsets.all(5),
              child: TextField(
                controller: controller,//最大长度,设置此项会让 TextField 右下角有一个输入数量的统计字符串
                maxLength: 10,// 最大行数
                maxLines: 1,// 是否自动更正
                autocorrect: true,// 是否自动对焦
                autofocus: true,//是否是密码
                obscureText: false,//键盘类型
                keyboardType: TextInputType.text,// 文本对齐方式
                textAlign: TextAlign.center,//控制键盘的功能键 指enter键,比如此处设置为next时,enter键显示的文字内容为 下一项
                textInputAction: TextInputAction.next,//输入文本的样式
                style: TextStyle(fontSize: 26.0, color: Colors.green),//内容改变的回调
                onChanged: (text) {},//长按时弹出的菜单,有copy、cut、paste、selectAll
                toolbarOptions: ToolbarOptions(
                    copy: true, cut: true, paste: true, selectAll: true),//内容提交(按回车)的回调
                onSubmitted: (text) {},//按回车时调用
                onEditingComplete: () {
                  print('onEditingComplete');
                },//是否允许输入
                enabled: true,//焦点
                focusNode: _focusNode,//控制光标的是否显示
                showCursor: true,//光标粗细
                cursorWidth: 3,//光标圆角
                cursorRadius: Radius.circular(10),//光标颜色。不设置默认系统主题色
                cursorColor: Colors.red,//装饰
                decoration: InputDecoration(
                    fillColor: Colors.grey.shade200,
                    filled: true,//显示在输入框的左下部,用于提示用户
                    helperText: "用户",
                    helperStyle: TextStyle(color: Colors.green),//输入框前面的图标 prefix在输入框的前部
                    prefixIcon: Icon(Icons.person),//输入框后面的文本 注:suffix在输入框的尾部
                    suffixText: "用户名",//文本样式
                    suffixStyle: TextStyle(fontSize: 14)),
              ),
            ),
            Divider(
              height: 1,
            ),
            SizedBox(height: 20.0),
            PrimaryColorOverride(
              color: Colors.black,
              child: TextField(
                controller: _phoneNumController,
                style: TextStyle(fontSize: 18.0, letterSpacing: 4.0),
                decoration: const InputDecoration(
                    //控制是否显示labelText auto 自动, never一直不显示,always一直显示
                    floatingLabelBehavior: FloatingLabelBehavior.auto,
                    //显示在输入框上边
                    labelText: '手机号',
                    //文本样式
                    labelStyle: TextStyle(fontSize: 16.0, letterSpacing: 0.0)),
                maxLines: 1,
                keyboardType: TextInputType.number,//限制用户输入的内容
                inputFormatters: [//限制长度LengthLimitingTextInputFormatter(11),//输入格式匹配
                  WhitelistingTextInputFormatter.digitsOnly
                ],
                enableInteractiveSelection: false,
                onChanged: (text) {},
              ),
            ),
            SizedBox(height: 20.0),
            PrimaryColorOverride(
              color: Colors.black,
              child: TextField(
                controller: _pwdController,
                style: TextStyle(fontSize: 18.0, letterSpacing: 4.0),
                decoration: const InputDecoration(
                    labelText: '密码',
                    labelStyle: TextStyle(fontSize: 16.0, letterSpacing: 0.0)),
                maxLines: 1,
                obscureText: true,
                keyboardType: TextInputType.number,
                inputFormatters: [LengthLimitingTextInputFormatter(16),
                  WhitelistingTextInputFormatter.digitsOnly,
                ],
                enableInteractiveSelection: false,
                onChanged: (text) {},
              ),
            ),
            Divider(
              height: 1,
            ),
            ListTile(
              leading: Text("车主",
                  style: TextStyle(fontSize: 16.0, color: Color(0xFF787878))),
              title: Container(
                alignment: Alignment.centerRight,
                child: SingleChildScrollView(
                  child: TextField(
                    controller:
                        TextEditingController.fromValue(TextEditingValue(// 设置内容
                            text: name,// 保持光标在最后
                            selection: TextSelection.fromPosition(
                              TextPosition(
                                  affinity: TextAffinity.downstream,
                                  offset: name?.length ?? 0),
                            ))),
                    decoration: InputDecoration(//当输入框为空时的提示,不为空时不在显示
                      hintText: '请输入',
                      border: InputBorder.none,
                      contentPadding: const EdgeInsets.symmetric(vertical: 3),
                    ),
                    textAlign: TextAlign.right,
                    style: new TextStyle(
                      color: Color(0xFFAAAAAA),
                    ),
                    autofocus: false,//内容改变的回调
                    onChanged: (text) {
                      name = text;
                    },
                  ),
                ),
              ),
            ),
            Divider(
              height: 1,
            ),
            Container(
              height: 60,
              width: 250,
              margin: EdgeInsets.fromLTRB(20, 20, 20, 0),
              child: TextField(
                decoration: InputDecoration(
                  fillColor: Color(0x30cccccc),
                  filled: true,
                  enabledBorder: OutlineInputBorder(
                      borderSide: BorderSide(color: Color(0x00FF0000)),
                      borderRadius: BorderRadius.all(Radius.circular(100))),
                  hintText: 'QQ号/手机号/邮箱',
                  focusedBorder: OutlineInputBorder(
                      borderSide: BorderSide(color: Color(0x00000000)),
                      borderRadius: BorderRadius.all(Radius.circular(100))),
                ),
              ),
            )
          ],
        ));
  }
}class PrimaryColorOverride extends StatelessWidget {const PrimaryColorOverride({Key key, this.color, this.child})
      : super(key: key);final Color color;final Widget child;@overrideWidget build(BuildContext context) {return Theme(
      child: child,
      data: Theme.of(context).copyWith(
        primaryColor: color,
        inputDecorationTheme: InputDecorationTheme(
          border: CutCornersBorder(),
        ),
      ),
    );
  }
}

效果:

android flutter 输入框光标不能移动 flutter 自定义输入框_jsp点击按钮弹出输入框