Handle changes to a text field
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.
How do you run a callback function every time the text changes? With Flutter, you have two options:
-
Supply an
onChanged()
callback to aTextField
or aTextFormField
. -
Use a
TextEditingController
.
1. Supply an onChanged()
callback to a TextField
or a TextFormField
The simplest approach is to supply an onChanged()
callback to a TextField
or a TextFormField
. Whenever the text changes, the callback is invoked.
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");
},
);
2. Use a TextEditingController
A more powerful, but more elaborate approach, is to supply a TextEditingController
as the controller
property of the TextField
or a TextFormField
.
To be notified when the text changes, listen to the controller using the addListener()
method using the following steps:
-
Create a
TextEditingController
. -
Connect the
TextEditingController
to a text field. - Create a function to print the latest value.
- Listen to the controller for changes.
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.
}
}
Connect the TextEditingController
to a text field
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
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
Finally, listen to the TextEditingController
and call the _printLatestValue()
method when the text changes. Use the addListener()
method for this purpose.
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);
}
}