This page describes how to set up basic text input for Flutter applications.

Choosing a widget

TextField is the most commonly used text input widget.

By default, a TextField is decorated with an underline. You can add a label, an icon, inline hint text, and error text by supplying an [InputDecoration( as the decoration property of the TextField. To remove the decoration entirely (including the underline and the space reserved for the label), set the decoration to null explicitly.

TextFormField wraps a TextField and integrates it with the enclosing Form. Use a TextFormField when you want to supply a validator function to check whether the user’s input satisfies some constraint (e.g., is a phone number) or when you wish to integrate a TextField with other FormField widgets.

Retrieving user input

There are two main approaches for retrieving the user’s input: (a) handling the onChanged callback and (b) supplying a TextEditingController.


Whenever the user types into the TextField, the TextField will call its onChanged callback. You can handle this callback to watch what the user types. For example, if you’re implementing a search field, you might want to update the search results as the user types their query.


A more powerful (but more elaborate) approach is supply a TextEditingController as the controller property of the TextField. The controller’s text and selection properties are updated continuously as the user types in the TextField. To be notified when these properties change, you listen to the controller using its addListener method. (If you add a listener, remember to remove the listener during your State object’s dispose method).

The TextEditingController also lets you control the contents of the TextField. If you modify the text or selection properties of the controller, the TextField will update to display the modified text or selection. For example, you can use this feature to implement inline autocomplete by adding the suggested text as a selected suffix to the text the user has typed.


Below is an example of using a TextEditingController to read the value the user has typed into a TextField:

/// Opens an [AlertDialog] showing what the user typed.
class ExampleWidget extends StatefulWidget {
  ExampleWidget({Key key}) : super(key: key);

  _ExampleWidgetState createState() => new _ExampleWidgetState();

/// State for [ExampleWidget] widgets.
class _ExampleWidgetState extends State<ExampleWidget> {
  final TextEditingController _controller = new TextEditingController();

  Widget build(BuildContext context) {
    return new Column(
      children: <Widget>[
        new TextField(
          controller: _controller,
          decoration: new InputDecoration(
            hintText: 'Type something',
        new RaisedButton(
          onPressed: () {
              context: context,
              child: new AlertDialog(
                title: new Text('What you typed'),
                content: new Text(_controller.text),
          child: new Text('DONE'),