响应文本框内容的更改
在某些情境中,我们可能需要在每次文本框的文本内容变化时都调用回调函数。例如,当构建一个有自动填充功能的搜索页面时,我们希望根据用户输入的内容来更新返回的结果。
In some cases, it’s useful to run a callback function every time the text in a text field changes. For example, you might want to build a search screen with autocomplete functionality where you want to update the results as the user types.
那么如何每次在文本内容改变时调用回调函数呢?在Flutter中,我们提供了两种选择:
How do you run a callback function every time the text changes? With Flutter, you have two options:
-
给
TextField
或TextFormField
绑定onChanged()
回调Supply an
onChanged()
callback to aTextField
or aTextFormField
. -
使用
TextEditingController
Use a
TextEditingController
.
TextField
或 TextFormField
绑定 onChanged()
回调
1. 给
onChanged()
callback to a TextField
or a TextFormField
1. Supply an 最简单的方法是给 TextField
绑定 onChanged()
回调。每当文本内容改变时,回调函数会被触发。
The simplest approach is to supply an onChanged()
callback to a
TextField
or a TextFormField
.
Whenever the text changes, the callback is invoked.
在下面的示例中,每次 text 的值改变,会在控制台中打印出当前文本框的值。
In this example, print the current value of the text field to the console every time the text changes.
TextField(
onChanged: (text) {
print("First text field: $text");
},
);
TextEditingController
2. 使用
TextEditingController
2. Use a 另外一种更强大但是更复杂的方法是绑定 TextEditingController
作为 TextField
和
TextFormField
的 controller
属性。
A more powerful, but more elaborate approach, is to supply a
TextEditingController
as the controller
property of the TextField
or a TextFormField
.
你可以通过如下步骤,使用 addListener()
方法来监听控制,实现在文本更改时收到通知:
To be notified when the text changes, listen to the controller
using the addListener()
method using the following steps:
-
创建一个
TextEditingController
Create a
TextEditingController
. -
将
TextEditingController
绑定到 text fieldConnect the
TextEditingController
to a text field. -
创建一个函数来打印最新值
Create a function to print the latest value.
-
监听控制器的变化
Listen to the controller for changes.
TextEditingController
创建一个
TextEditingController
Create a 创建一个 TextEditingController
:
Create a TextEditingController
:
// Define a custom Form widget.
class MyCustomForm extends StatefulWidget {
@override
_MyCustomFormState createState() => _MyCustomFormState();
}
// Define a corresponding State class.
// This class holds data related to the Form.
class _MyCustomFormState extends State<MyCustomForm> {
// Create a text controller. Later, use it to retrieve the
// current value of the TextField.
final myController = TextEditingController();
@override
void dispose() {
// Clean up the controller when the widget is removed from the
// widget tree.
myController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
// Fill this out in the next step.
}
}
TextEditingController
给 text field 绑定
TextEditingController
to a text field
Connect the TextEditingController
必须绑定到 TextField
或者是 TextFormField
才能被正常的使用。一旦绑定,就能够开始监听文本框的变化。
Supply the TextEditingController
to either a TextField
or a TextFormField
. Once you wire these two classes together,
you can begin listening for changes to the text field.
TextField(
controller: myController,
);
创建一个打印当前值的方法
Create a function to print the latest value
现在,我们需要一个每当表单项变化都会运行的函数。在下面的示例中,我们会在 _MyCustomFormState
类中创建一个方法,实现打印出文本框当前值。
You need a function to run every time the text changes.
Create a method in the _MyCustomFormState
class that prints
out the current value of the text field.
_printLatestValue() {
print("Second text field: ${myController.text}");
}
监听控制器的变化
Listen to the controller for changes
最后,需要监听 TextEditingController
并且在 text 值变化时运行
_printLatestValue()
方法。我们需要使用 addListener()
方法来实现这个功能。
Finally, listen to the TextEditingController
and call the
_printLatestValue()
method when the text changes. Use the
addListener()
method for this purpose.
下面的示例会在类 _MyCustomFormState
初始化的时候开始监听变化,dispose 时停止监听。
Begin listening for changes when the
_MyCustomFormState
class is initialized,
and stop listening when the _MyCustomFormState
is disposed.
class _MyCustomFormState extends State<MyCustomForm> {
@override
void initState() {
super.initState();
// Start listening to changes.
myController.addListener(_printLatestValue);
}
}
交互式样例
Interactive example
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Retrieve Text Input',
home: MyCustomForm(),
);
}
}
// Define a custom Form widget.
class MyCustomForm extends StatefulWidget {
@override
_MyCustomFormState createState() => _MyCustomFormState();
}
// Define a corresponding State class.
// This class holds data related to the Form.
class _MyCustomFormState extends State<MyCustomForm> {
// Create a text controller and use it to retrieve the current value
// of the TextField.
final myController = TextEditingController();
@override
void initState() {
super.initState();
myController.addListener(_printLatestValue);
}
@override
void dispose() {
// Clean up the controller when the widget is removed from the widget tree.
// This also removes the _printLatestValue listener.
myController.dispose();
super.dispose();
}
_printLatestValue() {
print("Second text field: ${myController.text}");
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Retrieve Text Input'),
),
body: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
children: <Widget>[
TextField(
onChanged: (text) {
print("First text field: $text");
},
),
TextField(
controller: myController,
),
],
),
),
);
}
}