欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Flutter 基础篇(九)—— 输入框

程序员文章站 2022-05-29 18:15:01
...

在 Material 组件库中,提供了 TextField 和 Form 分别来表示输入框和表单。

TextField

TextField 用于文本输入,它提供了很多属性,先来看它的定义:

const TextField({
  ...
  TextEditingController controller, 
  FocusNode focusNode,
  InputDecoration decoration = const InputDecoration(),
  TextInputType keyboardType,
  TextInputAction textInputAction,
  TextStyle style,
  TextAlign textAlign = TextAlign.start,
  bool autofocus = false,
  bool obscureText = false,
  int maxLines = 1,
  int maxLength,
  bool maxLengthEnforced = true,
  ValueChanged<String> onChanged,
  VoidCallback onEditingComplete,
  ValueChanged<String> onSubmitted,
  List<TextInputFormatter> inputFormatters,
  bool enabled,
  this.cursorWidth = 2.0,
  this.cursorRadius,
  this.cursorColor,
  ...
})
  • controller —— 编辑框的控制器,通过它可以设置/获取编辑框的内容、选择编辑内容、监听编辑文本改变事件。大多数情况下,我们都需要提供一个 controller 来与文本框进行交互。如果没有提供,则由 TextField 内部自动创建一个。
  • focusNode —— 用于控制 TextField 是否占有当前键盘的输入焦点。它是我们和键盘交互的一个句柄。
  • InputDecoration —— 用于控制 TextField 的外观显示,如提示文本、背景颜色、边框等。
  • keyboardType —— 用于设置该输入框默认的键盘输入类型,取值如下:
TextInputType枚举值 含义
text 文本输入键盘
multiline 多行文本,需要和 maxLines 配合
number 数字,*,#
datetime 日期输入框
emailAddress 电子邮件输入框
url url输入框

textInputAction —— 键盘动作按钮图标(即回车键位置图标),可选值有多个,具体可参考API文档,下面的值是 TextInputAction.search
Flutter 基础篇(九)—— 输入框

  • style :—— 正在编辑的文本的样式
  • textAlign —— 输入框内编辑文本在水平方向的对齐方式
  • autofocus —— 是否自动获取焦点
  • obscureText —— 是否隐藏正在编辑的文本,如用于输入密码的场景,文本内容会被 * 代替
  • maxLines —— 输入框的最大行数,默认为1,如果设置为 null ,则表示无限
  • maxLengthmaxLengthEnforced —— maxLength 代表输入框文本的最大长度,设置后输入框右下角会线束输入的文本计数。- maxLengthEnforced 决定当输入文本长度超过 maxLength 时是否阻止输入,为 true 时会阻止输入,为 false 时不会阻止输入但输入框会变红。
  • onChange —— 输入框内容改变时的回调函数
  • onEditingCompleteonSubmitted :这两个回调函数都是在输入框输入完成时触发的,比如按了键盘的完成。不同的是两个函数的签名,onSubmitted 回调是 ValueChanged<String> 类型,它接收当前输入的内容作为参数,而 onEditingComplete 不接受参数。
  • inputFormatters —— 用于指定输入格式,当用户输入内容改变时,会根据指定的格式来校验。
  • enable —— 如果为 false,则输入框会被禁用,禁用状态不接受输入和事件。
  • cursorWidthcursorRadiuscursorColor —— 这三个属性用于自定义输入框的光标宽度、圆角和颜色。

示例

通过下面的示例来演示获取输入框数据的两种方式。

结构:

Column(
  children: <Widget>[
     TextField(
       autofocus: true,
       decoration: InputDecoration(
         labelText: '用户名',
         hintText: '用户名或邮箱',
         prefixIcon: Icon(Icons.person)
       ),
     ),
     TextField(
       decoration: InputDecoration(
         labelText: '密码',
         hintText: '密码',
         prefixIcon: Icon(Icons.lock)
       ),
       obscureText: true,
     )
   ],
 );

方法一:在每个表单组件内定义 onChange 回调,在回调中改变状态,这种方法比较简单,在此就省略代码了。

方法二:通过 controller 直接获取。

定义一个 controller

TextEditingController _usernameController = TextEditingController();

在文本框中设置 controller

TextField(
  controller: _usernameController, //设置controller
  autofocus: true,
  decoration: InputDecoration(
    labelText: '用户名',
    hintText: '用户名或邮箱',
    prefixIcon: Icon(Icons.person)
  ),
)

然后就可以通过这个控制器来获取到文本框的信息,比如获取文本框的内容:

print(_usernameController.text);

上面的这两种方式相比,通过 onChanged 是专门用于监听文本变化的,而 controller 的功能却多一些,除了可以监听文本的变化以外,还可以设置默认值、选择文本等等。

设置默认值的方法也很简单,在 build 方法中构建组件之前(return 语句执行之前)将控制器的 text 属性设置为需要的默认值,比如:

_usernameController.text = 'jonas';

输入框焦点控制

焦点可以通过 FocusNodeFocusScopeNode 来控制,默认情况下,焦点由 FocusScope 来管理,它代表焦点的控制范围,可以在这个范围内通过 FocusScopeNode 在输入框之间移动焦点、设置默认焦点等。

可以通过 FocusScope.of(context) 来获取 Widget 树中默认的 FocusScopeNode ,注:contextbuild 方法中的参数。

下面来看一个示例,在此示例中,创建两个文本输入框,第一个自动获取焦点,然后创建两个按钮,点击第一个按钮可以将焦点从第一个输入框移动到第二个输入框;点击第二个按钮可以关闭键盘。

定义两个 FocusNode 用于与两个输入框绑定,声明一个 FocusScope 用于待会存储从 Widget 树中获取的对象:

FocusNode usernameFocusNode = new FocusNode();
FocusNode passwordFocusNode = new FocusNode();
FocusScopeNode focusScopeNode;
Widget build(BuildContext context) {
  // TODO: implement build
  return Column(
    children: <Widget>[
      TextField(
        focusNode: usernameFocusNode, //绑定输入框
        autofocus: true,
        decoration: InputDecoration(
          labelText: '用户名',
          hintText: '用户名或邮箱',
          prefixIcon: Icon(Icons.person)
        ),
      ),
      TextField(
        focusNode: passwordFocusNode, //绑定输入框
        decoration: InputDecoration(
          labelText: '密码',
          hintText: '密码',
          prefixIcon: Icon(Icons.lock)
        ),
        obscureText: true,
      ),
      FlatButton(
        child: Text('移动焦点'),
        onPressed: (){
          if(focusScopeNode == null){
            focusScopeNode = FocusScope.of(context);//获取这个Widget的focusScope
          }
          focusScopeNode.requestFocus(passwordFocusNode);//切换焦点
        },
      ),
      FlatButton(
        child: Text('隐藏键盘'),
        onPressed: (){
          //将所有焦点失去则自动收回键盘
          usernameFocusNode.unfocus();
          passwordFocusNode.unfocus();
        },
      )
    ],
  );
}

最后,对于焦点的变化的变化可以通过下面的方式来监听:

usernameFocusNode.addListener((){
  print(usernameFocusNode.hasFocus);
});