Handling Text Input
1. Using TextField Widget
| Property | Values | Description |
|---|---|---|
| controller | TextEditingController |
Controls the text field's value and selection. |
| decoration | InputDecoration |
Customizes the appearance of the text field (e.g., label, hint). |
| keyboardType | TextInputType |
Determines the type of keyboard to show (e.g., TextInputType.text, TextInputType.number). |
| obscureText | bool |
Displays input as bullets (e.g., for passwords). |
| maxLines | int? |
Number of lines the text field can display (null for unlimited). |
| onSubmitted | Function(String)? |
Callback when the user submits the text (e.g., pressing Enter). |
Example: Basic TextField
TextField(
decoration: InputDecoration(
labelText: 'Enter your name',
hintText: 'Type here...',
),
)
Example: Password Field
TextField(
obscureText: true,
decoration: InputDecoration(
labelText: 'Password',
suffixIcon: IconButton(
icon: Icon(Icons.visibility),
onPressed: () {},
),
),
)
Note: Use
TextFormField for form validation and integration with Form.
2. Using TextFormField Widget
| Property | Values | Description |
|---|---|---|
| controller | TextEditingController |
Controls the text input field's value and selection. |
| decoration | InputDecoration |
Defines the visual appearance and hint text of the field. |
| keyboardType | TextInputType |
Specifies the type of keyboard to show (e.g., TextInputType.text, TextInputType.number). |
| obscureText | bool |
Whether to hide the input (e.g., for passwords). |
| maxLines | int |
Maximum number of lines the field can expand to. Default is 1. |
| onChanged | Function(String) |
Callback when the text changes. |
| validator | Function(String) |
Validation function returning an error message or null. |
Example: Basic TextFormField Usage
TextFormField(
controller: TextEditingController(),
decoration: InputDecoration(
labelText: 'Enter your name',
hintText: 'Name',
),
validator: (value) {
if (value == null || value.isEmpty) {
return 'Please enter some text';
}
return null;
},
)
Example: Password TextFormField
TextFormField(
controller: TextEditingController(),
decoration: InputDecoration(
labelText: 'Password',
hintText: 'Enter password',
suffixIcon: IconButton(
icon: Icon(Icons.visibility),
onPressed: () {},
),
),
obscureText: true,
validator: (value) {
if (value == null || value.length < 6) {
return 'Password must be at least 6 characters';
}
return null;
},
)
Note: The
TextFormField widget is part of the Form widget and supports validation. It automatically integrates with TextEditingController for managing input state.
3. Using TextEditingController
The TextEditingController is a core class in Flutter for managing text input and state. It allows you to programmatically control the content of TextField or TextFormField widgets.
| Property | Description | Example |
|---|---|---|
| text | Current text value of the controller | "Hello World" |
| selection | Current text selection range | TextSelection.collapsed(offset: 5) |
| value | Complete TextEditingValue object |
TextEditingValue(text: "Hello", selection: ...) |
Example: Initializing and Using TextEditingController
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: Text("TextEditingController Example")),
body: Padding(
padding: EdgeInsets.all(16.0),
child: MyTextField(),
),
),
);
}
}
class MyTextField extends StatefulWidget {
@override
_MyTextFieldState createState() => _MyTextFieldState();
}
class _MyTextFieldState extends State<MyTextField> {
final TextEditingController _controller = TextEditingController();
@override
void dispose() {
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Column(
children: [
TextField(
controller: _controller,
decoration: InputDecoration(hintText: "Enter text here"),
),
SizedBox(height: 20),
Text("Current text: ${_controller.text}"),
],
);
}
}
Example: Setting and Updating Text Programmatically
class TextUpdateExample extends StatefulWidget {
@override
_TextUpdateExampleState createState() => _TextUpdateExampleState();
}
class _TextUpdateExampleState extends State<TextUpdateExample> {
final TextEditingController _controller = TextEditingController();
void _updateText() {
setState(() {
_controller.text = "Updated text!";
});
}
@override
Widget build(BuildContext context) {
return Column(
children: [
TextField(controller: _controller),
ElevatedButton(
onPressed: _updateText,
child: Text("Update Text"),
),
],
);
}
}
Note: Always dispose of
TextEditingController in the dispose method to prevent memory leaks.
Warning: Do not call
dispose on the controller more than once.
4. Managing Focus
| Property | Description | Usage |
|---|---|---|
| focusNode | Controls the focus state of a TextField or TextFormField. | FocusNode focusNode = FocusNode(); |
| requestFocus | Requests focus for the widget associated with this FocusNode. | FocusScope.of(context).requestFocus(focusNode); |
| unfocus | Removes focus from the current widget. | FocusScope.of(context).unfocus(); |
Example: Managing Focus in a TextField
class FocusExample extends StatefulWidget {
@override
_FocusExampleState createState() => _FocusExampleState();
}
class _FocusExampleState extends State<FocusExample> {
final FocusNode _focusNode = FocusNode();
@override
void dispose() {
_focusNode.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Column(
children: [
TextField(
focusNode: _focusNode,
decoration: InputDecoration(
labelText: 'Enter text',
),
),
ElevatedButton(
onPressed: () {
FocusScope.of(context).requestFocus(_focusNode);
},
child: Text('Focus TextField'),
),
],
);
}
}
Note: Always dispose of FocusNode instances to prevent memory leaks.
5. Using InputDecoration
| Property | Values | Description |
|---|---|---|
| hintText | String |
Displays a hint text when the field is empty |
| labelText | String |
Displays a label above the input field |
| prefixText | String |
Displays text before the input field |
| suffixText | String |
Displays text after the input field |
| icon | Widget |
Displays an icon at the start of the input field |
| border | InputBorder |
Defines the border style of the input field |
| focusedBorder | InputBorder |
Defines the border when the input is focused |
| enabledBorder | InputBorder |
Defines the border when the input is enabled but not focused |
| errorText | String |
Displays an error message below the input field |
| errorStyle | TextStyle |
Defines the style of the error text |
Example: Basic InputDecoration
TextField(
decoration: InputDecoration(
labelText: 'Email',
hintText: 'Enter your email',
prefixText: '@',
icon: Icon(Icons.email),
),
)
Example: InputDecoration with Border
TextField(
decoration: InputDecoration(
labelText: 'Password',
hintText: 'Enter your password',
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(8),
borderSide: BorderSide(color: Colors.blue),
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(8),
borderSide: BorderSide(color: Colors.red, width: 2),
),
),
)
6. Customizing Input Borders
| Property | Values | Description |
|---|---|---|
| border | InputBorder.none, InputBorder.line, InputBorder.underline |
Defines the type of border to display around the input field. |
| focusedBorder | OutlineInputBorder, UnderlineInputBorder |
Border displayed when the input field is focused. |
| enabledBorder | OutlineInputBorder, UnderlineInputBorder |
Border displayed when the input field is enabled but not focused. |
| errorBorder | OutlineInputBorder, UnderlineInputBorder |
Border displayed when the input field has an error. |
Example: Customizing Input Borders
TextField(
decoration: InputDecoration(
border: OutlineInputBorder(
borderSide: BorderSide(color: Colors.blue, width: 2.0),
),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.red, width: 2.0),
),
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.grey, width: 1.0),
),
errorBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.red, width: 2.0),
),
),
)
7. Using Input Formatters
| Property | Description | Usage |
|---|---|---|
| inputFormatters | Applies formatters to the input text | [WhitelistingTextInputFormatter.digitsOnly] |
Example: Restricting input to digits only
TextField(
inputFormatters: [WhitelistingTextInputFormatter.digitsOnly],
keyboardType: TextInputType.number,
)
Example: Formatting phone numbers
TextField(
inputFormatters: [
MaskedTextInputFormatter(
mask: '(000) 000-0000',
placeholder: ' ',
),
],
keyboardType: TextInputType.phone,
)
8. Using Input Actions
| Action | Description | Usage |
|---|---|---|
| TextInputAction.newline | Indicates that the user wants to insert a new line. | TextInputAction.newline |
| TextInputAction.done | Indicates that the user is done editing and wants to close the keyboard. | TextInputAction.done |
| TextInputAction.go | Indicates that the user wants to go to a specific location or page. | TextInputAction.go |
| TextInputAction.search | Indicates that the user wants to search for content. | TextInputAction.search |
| TextInputAction.send | Indicates that the user wants to send a message or content. | TextInputAction.send |
| TextInputAction.next | Indicates that the user wants to move to the next input field. | TextInputAction.next |
| TextInputAction.previous | Indicates that the user wants to move to the previous input field. | TextInputAction.previous |
Example: Setting Input Action
TextField(
keyboardType: TextInputType.text,
textInputAction: TextInputAction.done,
onSubmitted: (value) {
print('Submitted value: $value');
},
)
9. Using Keyboard Types
| Keyboard Type | Description | Use Case |
|---|---|---|
| TextInputType.text | Standard text input field. | General text entry, such as names or comments. |
| TextInputType.number | Input for numeric values only. | Entering numbers like age, quantity, or price. |
| TextInputType.phone | Input for phone numbers with dial pad. | Collecting phone numbers with formatting assistance. |
| TextInputType.email | Input for email addresses with @ symbol. | Entering email addresses with auto-suggestions. |
| TextInputType.url | Input for URLs with http/https prefix. | Collecting web addresses or links. |
| TextInputType.datetime | Input for date and time values. | Entering dates or times with calendar pickers. |
| TextInputType.multiline | Multi-line text input. | Allowing users to enter paragraphs or descriptions. |
Example: Setting Keyboard Type
TextField(
keyboardType: TextInputType.number,
decoration: InputDecoration(
labelText: 'Age',
hintText: 'Enter your age',
),
)
10. Implementing Obscure Text
| Property | Values | Description |
|---|---|---|
| obscureText | true | false |
When set to true, masks the text input (e.g., for passwords). |
| obscuringCharacter | String |
Character used to obscure text. Defaults to •. |
Example: Password Input Field
TextField(
obscureText: true,
decoration: InputDecoration(
labelText: 'Password',
hintText: 'Enter your password',
),
)
Note: Setting
obscureText to true hides the actual text input and displays obscuringCharacter instead.
11. Using autocorrect and enableSuggestions Properties
| Property | Description | Values | Default |
|---|---|---|---|
| autocorrect | Enables or disables automatic correction of words as the user types. | true / false |
true |
| enableSuggestions | Enables or disables suggestions for words as the user types. | true / false |
true |
Example: Configuring autocorrect and enableSuggestions
TextField(
autocorrect: false,
enableSuggestions: false,
)
Note: These properties are useful for custom input fields where you want to control the text input behavior, such as in password fields or when implementing custom keyboards.