深入Flutter TextField

Flutter TextField

Posted by Kinsomy on December 14, 2018

翻译原文来自 https://medium.com/flutter-community/a-deep-dive-into-flutter-textfields-f0e676aaab7a

TextField介绍

TextField允许从用户处收集信息,声明一个基础的TextField代码十分简单:

TextField()

这会创建一个基础TextField组件:

从TextField收集信息

由于TextFields没有像Android中那样有一个ID,因此无法根据需要检索文本,而必须在更改时将其存储在变量中或使用控制器。

1.最简单的方式就是使用onChanged回调方法,将TextField当前的值保存在一个变量内,下面是示例代码。

String value = "";
TextField(
  onChanged: (text) {
    value = text;
  },
)

2.第二种方式就是使用TextEditingController。控制器依附在TextField组件上,并且我们可以监听和控制TextField的文本。

TextEditingController controller = TextEditingController();
TextField(
  controller: controller,
)

接着就可以使用下面代码监听变化:

controller.addListener(() {
  // Do something here
});

用控制器获取和设置文本:

print(controller.text); // Print current value
controller.text = "Demo Text"; // Set new value

TextField的其他回调

//键盘上按了done
onEditingComplete: () {},
onSubmitted: (value) {},

TextField获得焦点

TextField获得焦点意味着有一个TextField被激活并且任何来自键盘的输入都会被键入到获得焦点的TextField内。

1.自动获得焦点

为了让TextField在widget创建的时候自动获取焦点,设置autofocus属性为true。

TextField(
  autofocus: true,
),

2.自定义焦点切换

如果我们想代码变化焦点而不是仅仅自动获得焦点需要怎么做呢?由于我们需要某种方式来引用我们想要关注的TextField,我们将FocusNode附加到TextField并使用它来切换焦点。

// Initialise outside the build method
FocusNode nodeOne = FocusNode();
FocusNode nodeTwo = FocusNode();
// Do this inside the build method
TextField(
  focusNode: nodeOne,
),
TextField(
  focusNode: nodeTwo,
),
RaisedButton(
  onPressed: () {
    FocusScope.of(context).requestFocus(nodeTwo);
  },
  child: Text("Next Field"),
),

这里我们创建了两个focus node并且将他们依附到TextField上,当点击NextField按钮时,使用FocusScope去为下一个TextField申请获取焦点。

TextField更换键盘属性

在Flutter中,TextField允许你定制和键盘相关的属性。

1.键盘类型

TextField可以在弹出键盘的时候修改键盘类型。使用以下代码:

TextField(
  keyboardType: TextInputType.number,
),

类型有如下几种:

  • TextInputType.text (Normal complete keyboard)
  • TextInputType.number (A numerical keyboard)
  • TextInputType.emailAddress (Normal keyboard with an “@”)
  • TextInputType.datetime (Numerical keyboard with a “/” and “:”)
  • TextInputType.multiline (Numerical keyboard with options to enabled signed and decimal mode)

2.键盘操作按钮行为

更改TextField的textInputAction可以更改键盘本身的操作按钮。

//发送操作
TextField(
  textInputAction: TextInputAction.send,
),

完整的行为列表太长,这里不做展示了,需要的可以进入TextInputAction类查看。

启用或禁用特定TextField的自动更正。使用自动更正字段进行设置。这同时也会禁用输入建议。

TextField(
  autocorrect: false,
),

3.文本大写

TextField提供了一些选项,用来对用户输入的文本大写化。

TextField(
  textCapitalization: TextCapitalization.sentences,
),

1.TextCapitalization.sentences

这是最常见的大写化类型,每个句子的第一个字母被转换成大写。

2.TextCapitalization.characters

大写句子中的所有字符。

3. TextCapitalization.words

对每个单词首字母大写。

文本对齐

使用textAlign属性设置TextField内的光标对齐方式。

TextField(
  textAlign: TextAlign.center,
),

光标和文字会从TextField组件中间开始。

还有其他属性包括,start, end, left, right, center, justify.

文本样式

我们使用style属性来更改TextField内部文本的外观。 使用它来更改颜色,字体大小等。这类似于文本小部件中的样式属性,因此我们不会花太多时间来探索它。

TextField(
  style: TextStyle(color: Colors.red, fontWeight: FontWeight.w300),
),

更换光标样式

可以直接从TextField小部件自定义光标。 您可以更改角落的光标颜色,宽度和半径。 例如,这里我制作一个圆形的红色光标。

TextField(
  cursorColor: Colors.red,
  cursorRadius: Radius.circular(16.0),
  cursorWidth: 16.0,
),

控制最大字符数

TextField(
  maxLength: 4,
),

设置maxLength属性后,TextField会默认添加一个长度计数器。

可扩展TextField

有时,我们需要一个TextField,当一行完成时会扩展。 在Flutter中,它有点奇怪(但很容易)。 为此,我们将maxLines设置为null,默认为1。 设置为null不是我们习以为常的东西,但是它很容易做到。

注意:将maxLines属性设置为一个确定的数值,会将TextField直接扩大到对应的最大行

TextField(
  maxLines: 3,
)

隐藏文本内容

TextField(
  obscureText: true,
),

装饰TextField

到目前为止,我们专注于Flutter提供的输入功能。 现在我们将实际设计一个花哨的TextField。 为了装饰TextField,我们使用带有InputDecoration的decoration属性。 由于InputDecoration类非常庞大,我们将尝试快速查看大多数重要属性。

hint和label

hint:

label:

图标

//输入框外图标
TextField(
  decoration: InputDecoration(
    icon: Icon(Icons.print)
  ),
),
//前缀图标
TextField(
  decoration: InputDecoration(
    prefixIcon: Icon(Icons.print)
  ),
),

//输入框前缀组件
TextField(
  decoration: InputDecoration(
    prefix: CircularProgressIndicator(),
  ),
),

每个属性像hint,label都有各自的style设置

1.用hintstyle修改hint样式

TextField(
  decoration: InputDecoration(
    hintText: "Demo Text",
    hintStyle: TextStyle(fontWeight: FontWeight.w300, color: Colors.red)
  ),
),

2.帮助性提示

和label不一样,它会一直显示在输入框下部

TextField(
  decoration: InputDecoration(
    helperText: "Hello"
  ),
),

3.使用decoration: null或者InputDecoration.collapsed可以去除默认的下划线。

TextField(
  decoration: InputDecoration.collapsed(hintText: "")
),

4.使用border给TextField设置边框

TextField(
  decoration: InputDecoration(
    border: OutlineInputBorder()
  )
),