The Flutter Text Field is a very important part when it comes to creating a full application depending on the kind of App (
Many of us came from a web background where from the very beginning there were HTML <forms>s with <input>s and <select>s. All of these exist to enable the user to get data into web apps, an activity we can’t live without in mobile apps as well. Flutter provides widgets for entering data as we have on the Web, but then, they don’t work the same way. They take much more work to create and use. Sorry about that. But they are also safer and give us much more control. Part of the complication is that these widgets don’t maintain their own state; you have to do it manually. Another part of the complication is that input widgets are unaware of each other. In other words, they don’t play well together until you group them with a Form widget. We eventually need to focus on the Form widget. But before we do, let’s know how to create the TextField now.
CAUTION: Input widgets are really tough to work with unless they are used within a StatefulWidget because, by nature, they change state.
If all you have is a single textbox, you probably want a TextField widget. Here’s a simple example of the TextField widget with a Text label above it:
const Text('Search terms'), TextField( onChanged: (String val) => _searchTerm = val, ),
onChanged property is an event handler that fires after every keystroke. It receives a single value – a String. This is the value that the user is typing. In the preceding example, we’re setting a local variable called _searchTerm to whatever the user types.
To provide an initial value with a TextField, you need the unnecessarily complex
TextEditingController _controller = TextEditingController(text: "Initial value here");
Then tell your
TextField about the controller
const Text('Search terms'), TextField( controller: _controller, onChanged: (String val) => _searchTerm = val, ),
You can also use that _controller.text property to retrieve the value that the user is typing into the box. Did you notice the Text(‘Search terms’)? That is our lame attempt at putting a label above the TextField. There’s a much, much better way.
How to make Your TextField fancy
There’s a ton of options to make your TextField more useful – not infinite options, but lots. And they’re all available through the InputDecoration widget.
return TextField( controller: _emailController, decoration: InputDecoration( labelText: 'Email', hintText: '[email protected]', icon: Icon(Icons.contact_mail), ), ),
Below are some
InputDecoration very helpful options
|Appears above the TextField. Tells the user what this TextField is for|
|Light ghost text inside the TextField. Disappears as the user begins typing|
|Error message that appears below the TextField. Usually in red. It is set automatically by validation (covered later), but you can set it manually if you need to|
|Text in the TextField to the left of the stuff the user types in|
|Same as prefixText but to the far right|
|Draws one inside the TextField to the left|
|Same as prefixIcon but to the far right|
|Draws an icon to the left of the entire TextField|
QUICK TIP: To make it a password box,
set obscureText property to true. As the user types, each character appears for a second and is replaced by a dot.
return TextField( obscureText: true, decoration: InputDecoration( labelText: 'Password', ),);
Want a special soft keyboard? No problem. Just use the
return TextField( keyboardType: TextInputType.number, );
TextInputType.email. Note the @ sign
Also, Take Note: If you want to limit the type of text that is allowed to be entered, you can do so with the TextInput’s
inputFormatters property. It’s actually an array so you can combine one or more of…
BlacklistingTextInputFormatter– Forbids certain characters from being entered. They just don’t appear when the user types.
WhitelistingTextInputFormatter– Allows only these characters to be entered. Anything outside this list doesn’t appear.
LengthLimitingTextInputFormatter– Can’t type more than X characters.
Those first two will allow you to use regular expressions to specify patterns that you want (white list) or don’t want (blacklist). Here’s an example:
return TextField( inputFormatters: [ WhitelistingTextInputFormatter(RegExp('[0-9 -]')), LengthLimitingTextInputFormatter(16) ], decoration: InputDecoration( labelText: 'Credit Card', ), );
WhitelistingTextInputFormatter, we’re only allowing numbers 0–9, a space, or a dash. Then the
LengthLimitingTextInputFormatter is keeping to a max of 16 characters.