Flutter TextField
TextField is one of the most commonly used input widgets in Flutter. It allows users to enter text such as names, email addresses, passwords, search terms, phone numbers, comments, and other information.
Flutter's TextField supports keyboard configuration, styling, icons, text controllers, input formatting, callbacks, password masking, multiline input, focus management, and many other features. Flutter also provides TextFormField, which integrates a text field with the Form widget for validation and form management. Official Flutter TextField Documentation
1. What Is TextField?
TextField is a Material Design widget used to receive text input from the user. It can work with both physical keyboards and on-screen keyboards.
Common Uses
- Login forms
- Registration forms
- Search boxes
- Username input
- Email input
- Phone number input
- Password input
- Address input
- Comments and feedback
- Chat messages
- Multiline descriptions
2. Basic TextField Syntax
TextField(
decoration: InputDecoration(
labelText: 'Name',
hintText: 'Enter your name',
),
)
This creates a basic text input field with a label and hint.
3. Simple TextField Example
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: Scaffold(
appBar: AppBar(
title: const Text('TextField Example'),
),
body: const Padding(
padding: EdgeInsets.all(20),
child: TextField(
decoration: InputDecoration(
labelText: 'Name',
hintText: 'Enter your name',
border: OutlineInputBorder(),
),
),
),
),
);
}
}
4. TextField with Label
The labelText property displays a label describing what the user should enter.
TextField(
decoration: const InputDecoration(
labelText: 'Full Name',
border: OutlineInputBorder(),
),
)
Example
TextField(
decoration: const InputDecoration(
labelText: 'Email Address',
border: OutlineInputBorder(),
),
)
5. TextField with Hint Text
hintText provides an example or instruction inside the input field. It disappears when the user starts entering text.
TextField(
decoration: const InputDecoration(
hintText: 'Enter your email address',
border: OutlineInputBorder(),
),
)
Label vs Hint
| Property |
Purpose |
labelText |
Describes the field and remains associated with the field as it is focused or filled. |
hintText |
Provides an example or instruction inside the empty field. |
6. InputDecoration
InputDecoration controls the visual appearance and supporting elements around a TextField.
Common properties include:
labelText
hintText
helperText
errorText
prefixIcon
suffixIcon
prefixText
suffixText
border
enabledBorder
focusedBorder
fillColor
filled
Example
TextField(
decoration: const InputDecoration(
labelText: 'Username',
hintText: 'Enter your username',
helperText: 'Use 3 to 20 characters',
border: OutlineInputBorder(),
),
)
7. OutlineInputBorder
OutlineInputBorder displays a rectangular border around the text field.
TextField(
decoration: const InputDecoration(
labelText: 'Username',
border: OutlineInputBorder(),
),
)
Rounded Border
TextField(
decoration: InputDecoration(
labelText: 'Username',
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(12),
),
),
)
8. UnderlineInputBorder
UnderlineInputBorder displays an underline beneath the field.
TextField(
decoration: const InputDecoration(
labelText: 'Username',
border: UnderlineInputBorder(),
),
)
9. TextField with Prefix Icon
The prefixIcon property displays an icon before the entered text.
TextField(
decoration: const InputDecoration(
labelText: 'Email',
hintText: 'Enter your email',
prefixIcon: Icon(Icons.email_outlined),
border: OutlineInputBorder(),
),
)
Common Prefix Icons
Icons.person
Icons.email
Icons.phone
Icons.lock
Icons.search
Icons.location_on
Icons.calendar_today
10. TextField with Suffix Icon
suffixIcon places an icon at the end of the input field.
TextField(
decoration: const InputDecoration(
labelText: 'Search',
suffixIcon: Icon(Icons.search),
border: OutlineInputBorder(),
),
)
11. Password TextField
Password fields commonly hide the entered characters using obscureText: true.
TextField(
obscureText: true,
decoration: const InputDecoration(
labelText: 'Password',
prefixIcon: Icon(Icons.lock_outline),
border: OutlineInputBorder(),
),
)
The obscureText property replaces the visible input with obscuring characters.
12. Password Visibility Toggle
A password visibility button allows the user to switch between hidden and visible password text.
class PasswordField extends StatefulWidget {
const PasswordField({super.key});
@override
State createState() => _PasswordFieldState();
}
class _PasswordFieldState extends State {
bool obscurePassword = true;
@override
Widget build(BuildContext context) {
return TextField(
obscureText: obscurePassword,
decoration: InputDecoration(
labelText: 'Password',
prefixIcon: const Icon(Icons.lock_outline),
suffixIcon: IconButton(
icon: Icon(
obscurePassword
? Icons.visibility
: Icons.visibility_off,
),
onPressed: () {
setState(() {
obscurePassword = !obscurePassword;
});
},
),
border: const OutlineInputBorder(),
),
);
}
}
13. TextField for Email
Use TextInputType.emailAddress when collecting email addresses so the platform can provide an appropriate keyboard.
TextField(
keyboardType: TextInputType.emailAddress,
decoration: const InputDecoration(
labelText: 'Email Address',
hintText: '[email protected]',
prefixIcon: Icon(Icons.email_outlined),
border: OutlineInputBorder(),
),
)
14. TextField for Phone Number
Use TextInputType.phone for phone number input.
TextField(
keyboardType: TextInputType.phone,
decoration: const InputDecoration(
labelText: 'Phone Number',
hintText: 'Enter your phone number',
prefixIcon: Icon(Icons.phone_outlined),
border: OutlineInputBorder(),
),
)
15. TextField for Number Input
Use an appropriate keyboard type when the field expects numeric input.
TextField(
keyboardType: TextInputType.number,
decoration: const InputDecoration(
labelText: 'Age',
border: OutlineInputBorder(),
),
)
For more specific input rules, input formatters can be used to control or format user input.
16. TextField for Multiline Input
By default, a TextField is single-line. You can use maxLines for multiline input.
TextField(
maxLines: 5,
decoration: const InputDecoration(
labelText: 'Description',
hintText: 'Write your description',
border: OutlineInputBorder(),
),
)
Unlimited Lines
TextField(
maxLines: null,
decoration: const InputDecoration(
labelText: 'Comments',
border: OutlineInputBorder(),
),
)
17. Controlling Minimum and Maximum Lines
TextField(
minLines: 3,
maxLines: 6,
decoration: const InputDecoration(
labelText: 'Message',
border: OutlineInputBorder(),
),
)
minLines specifies the minimum number of visible lines, while maxLines limits the maximum number of lines.
18. maxLength Property
The maxLength property limits the number of characters that can be entered.
TextField(
maxLength: 50,
decoration: const InputDecoration(
labelText: 'Username',
border: OutlineInputBorder(),
),
)
Flutter can display a character counter when maxLength is specified.
19. Reading Text with TextEditingController
A TextEditingController can be used to read and control the current text in a TextField. Flutter recommends disposing of the controller when it is no longer needed. Flutter TextEditingController Guide
class NameScreen extends StatefulWidget {
const NameScreen({super.key});
@override
State createState() => _NameScreenState();
}
class _NameScreenState extends State {
final nameController = TextEditingController();
@override
void dispose() {
nameController.dispose();
super.dispose();
}
void showName() {
print(nameController.text);
}
@override
Widget build(BuildContext context) {
return Column(
children: [
TextField(
controller: nameController,
decoration: const InputDecoration(
labelText: 'Name',
border: OutlineInputBorder(),
),
),
ElevatedButton(
onPressed: showName,
child: const Text('Get Name'),
),
],
);
}
}
20. Setting Initial Text
A controller can also be initialized with text.
final nameController = TextEditingController(
text: 'John Doe',
);
Then connect it to the field:
TextField(
controller: nameController,
)
21. Handling Changes with onChanged
The onChanged callback runs when the user changes the text in the field. It is useful for live search, character counting, filtering, and dynamic UI updates. Flutter TextField Change Handling
TextField(
onChanged: (value) {
print('Current value: $value');
},
)
Live Character Count
TextField(
onChanged: (value) {
print('Characters: ${value.length}');
},
)
22. Handling Submitted Text with onSubmitted
The onSubmitted callback is called when the user indicates that they have finished editing, such as by pressing an appropriate action button on the keyboard.
TextField(
onSubmitted: (value) {
print('Submitted: $value');
},
)
onChanged is useful for reacting to changes while typing, while onSubmitted is useful when the user finishes editing. TextField API Documentation
23. TextInputAction
textInputAction controls the action button shown by the software keyboard.
TextField(
textInputAction: TextInputAction.next,
decoration: const InputDecoration(
labelText: 'First Name',
border: OutlineInputBorder(),
),
)
Common Actions
TextInputAction.next
TextInputAction.previous
TextInputAction.done
TextInputAction.search
TextInputAction.go
TextInputAction.send
24. Moving Focus Between TextFields
Multiple input fields can be connected so that pressing the keyboard's Next action moves focus to the next field.
class UserForm extends StatefulWidget {
const UserForm({super.key});
@override
State createState() => _UserFormState();
}
class _UserFormState extends State {
final nameFocus = FocusNode();
final emailFocus = FocusNode();
@override
void dispose() {
nameFocus.dispose();
emailFocus.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Column(
children: [
TextField(
focusNode: nameFocus,
textInputAction: TextInputAction.next,
onSubmitted: (_) {
emailFocus.requestFocus();
},
decoration: const InputDecoration(
labelText: 'Name',
border: OutlineInputBorder(),
),
),
const SizedBox(height: 16),
TextField(
focusNode: emailFocus,
keyboardType: TextInputType.emailAddress,
textInputAction: TextInputAction.done,
decoration: const InputDecoration(
labelText: 'Email',
border: OutlineInputBorder(),
),
),
],
);
}
}
25. Text Capitalization
textCapitalization controls capitalization behavior for text input.
TextField(
textCapitalization: TextCapitalization.words,
decoration: const InputDecoration(
labelText: 'Full Name',
border: OutlineInputBorder(),
),
)
Available Options
TextCapitalization.none
TextCapitalization.characters
TextCapitalization.words
TextCapitalization.sentences
26. Text Alignment
The textAlign property controls the horizontal alignment of entered text.
TextField(
textAlign: TextAlign.center,
decoration: const InputDecoration(
labelText: 'OTP',
border: OutlineInputBorder(),
),
)
Common Values
TextAlign.start
TextAlign.center
TextAlign.end
TextAlign.left
TextAlign.right
27. Read-Only TextField
Use readOnly: true when the user should be able to interact with or select the field but should not edit its contents.
TextField(
readOnly: true,
controller: TextEditingController(
text: 'Account ID: 1001',
),
decoration: const InputDecoration(
labelText: 'Account ID',
border: OutlineInputBorder(),
),
)
A read-only field is different from a disabled field. A disabled field ignores interaction and is visually disabled.
28. Disabled TextField
Set enabled: false to disable the field.
TextField(
enabled: false,
decoration: const InputDecoration(
labelText: 'Disabled Field',
border: OutlineInputBorder(),
),
)
29. Autofocus
The autofocus property can request focus automatically when the field becomes available.
TextField(
autofocus: true,
decoration: const InputDecoration(
labelText: 'Search',
prefixIcon: Icon(Icons.search),
border: OutlineInputBorder(),
),
)
Use autofocus carefully because automatically opening the keyboard can be unexpected in some user flows.
30. Styling TextField Text
The style property controls the appearance of the entered text.
TextField(
style: const TextStyle(
fontSize: 18,
fontWeight: FontWeight.w500,
),
decoration: const InputDecoration(
labelText: 'Name',
border: OutlineInputBorder(),
),
)
31. Focused Border
You can provide a different border when the field is focused.
TextField(
decoration: InputDecoration(
labelText: 'Email',
border: const OutlineInputBorder(),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
borderSide: const BorderSide(
width: 2,
),
),
),
)
32. Enabled Border
enabledBorder controls the border when the field is enabled but not focused.
TextField(
decoration: InputDecoration(
labelText: 'Username',
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
borderSide: const BorderSide(
width: 1,
),
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
borderSide: const BorderSide(
width: 2,
),
),
),
)
33. Filled TextField
Setting filled: true allows the field to display a filled background.
TextField(
decoration: InputDecoration(
labelText: 'Username',
filled: true,
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(12),
),
),
)
34. TextField with Prefix and Suffix Text
TextField(
decoration: const InputDecoration(
labelText: 'Price',
prefixText: '₹ ',
suffixText: ' INR',
border: OutlineInputBorder(),
),
)
35. Helper Text and Error Text
helperText can provide additional instructions, while errorText can display an error message.
TextField(
decoration: const InputDecoration(
labelText: 'Username',
helperText: 'Choose a unique username',
errorText: 'Username already exists',
border: OutlineInputBorder(),
),
)
36. TextField Validation vs TextFormField
A basic TextField does not provide the same integrated form validation mechanism as TextFormField. If the field belongs to a larger Form and needs a validator, TextFormField is usually the appropriate choice. TextFormField API
| TextField |
TextFormField |
| General text input |
Form-integrated text input |
| Does not directly provide Form validation |
Supports validator |
| Useful for search and simple inputs |
Useful for structured forms |
| Can use controller |
Can use controller |
| Supports callbacks |
Supports callbacks plus form features |
37. TextField with Form
For validation-based forms, use TextFormField inside a Form.
final formKey = GlobalKey();
Form(
key: formKey,
child: Column(
children: [
TextFormField(
decoration: const InputDecoration(
labelText: 'Email',
border: OutlineInputBorder(),
),
validator: (value) {
if (value == null || value.isEmpty) {
return 'Please enter your email';
}
return null;
},
),
const SizedBox(height: 16),
FilledButton(
onPressed: () {
if (formKey.currentState!.validate()) {
print('Form is valid');
}
},
child: const Text('Submit'),
),
],
),
)
Flutter's official validation pattern uses a Form, a GlobalKey, and validators on TextFormField. Flutter Form Validation Guide
38. Input Formatters
Input formatters can be used when you need to transform or restrict text as the user types.
import 'package:flutter/services.dart';
TextField(
inputFormatters: [
FilteringTextInputFormatter.digitsOnly,
],
keyboardType: TextInputType.number,
decoration: const InputDecoration(
labelText: 'PIN',
border: OutlineInputBorder(),
),
)
Example: Allow Only Digits
inputFormatters: [
FilteringTextInputFormatter.digitsOnly,
]
Example: Limit Input Length
inputFormatters: [
LengthLimitingTextInputFormatter(10),
]
39. Search TextField
TextField is frequently used to build search interfaces.
TextField(
onChanged: (query) {
print('Searching for: $query');
},
decoration: InputDecoration(
hintText: 'Search products',
prefixIcon: const Icon(Icons.search),
suffixIcon: IconButton(
icon: const Icon(Icons.clear),
onPressed: () {},
),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(12),
),
),
)
40. Complete Login TextField Example
Column(
children: [
TextField(
keyboardType: TextInputType.emailAddress,
decoration: const InputDecoration(
labelText: 'Email',
hintText: 'Enter your email',
prefixIcon: Icon(Icons.email_outlined),
border: OutlineInputBorder(),
),
),
const SizedBox(height: 16),
TextField(
obscureText: true,
decoration: const InputDecoration(
labelText: 'Password',
hintText: 'Enter your password',
prefixIcon: Icon(Icons.lock_outline),
suffixIcon: Icon(Icons.visibility_off),
border: OutlineInputBorder(),
),
),
],
)
41. Complete Registration TextFields
Column(
children: [
TextField(
textCapitalization: TextCapitalization.words,
decoration: const InputDecoration(
labelText: 'Full Name',
prefixIcon: Icon(Icons.person_outline),
border: OutlineInputBorder(),
),
),
const SizedBox(height: 16),
TextField(
keyboardType: TextInputType.emailAddress,
decoration: const InputDecoration(
labelText: 'Email',
prefixIcon: Icon(Icons.email_outlined),
border: OutlineInputBorder(),
),
),
const SizedBox(height: 16),
TextField(
keyboardType: TextInputType.phone,
decoration: const InputDecoration(
labelText: 'Phone',
prefixIcon: Icon(Icons.phone_outlined),
border: OutlineInputBorder(),
),
),
const SizedBox(height: 16),
TextField(
obscureText: true,
decoration: const InputDecoration(
labelText: 'Password',
prefixIcon: Icon(Icons.lock_outline),
border: OutlineInputBorder(),
),
),
],
)
42. Practical User Profile Form
class ProfileScreen extends StatefulWidget {
const ProfileScreen({super.key});
@override
State createState() => _ProfileScreenState();
}
class _ProfileScreenState extends State {
final nameController = TextEditingController();
final emailController = TextEditingController();
final phoneController = TextEditingController();
@override
void dispose() {
nameController.dispose();
emailController.dispose();
phoneController.dispose();
super.dispose();
}
void saveProfile() {
print('Name: ${nameController.text}');
print('Email: ${emailController.text}');
print('Phone: ${phoneController.text}');
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Profile'),
),
body: SingleChildScrollView(
padding: const EdgeInsets.all(20),
child: Column(
children: [
TextField(
controller: nameController,
textCapitalization: TextCapitalization.words,
decoration: const InputDecoration(
labelText: 'Full Name',
prefixIcon: Icon(Icons.person_outline),
border: OutlineInputBorder(),
),
),
const SizedBox(height: 16),
TextField(
controller: emailController,
keyboardType: TextInputType.emailAddress,
decoration: const InputDecoration(
labelText: 'Email',
prefixIcon: Icon(Icons.email_outlined),
border: OutlineInputBorder(),
),
),
const SizedBox(height: 16),
TextField(
controller: phoneController,
keyboardType: TextInputType.phone,
decoration: const InputDecoration(
labelText: 'Phone',
prefixIcon: Icon(Icons.phone_outlined),
border: OutlineInputBorder(),
),
),
const SizedBox(height: 24),
SizedBox(
width: double.infinity,
child: FilledButton(
onPressed: saveProfile,
child: const Text('Save Profile'),
),
),
],
),
),
);
}
}
43. TextField Best Practices
- Use a clear
labelText to identify the purpose of the field.
- Use
hintText for useful examples or instructions.
- Choose the appropriate
keyboardType.
- Use
obscureText for password input.
- Use
TextEditingController when the application needs to read or control the value.
- Dispose controllers when they are no longer needed.
- Use
TextFormField when integrated form validation is required.
- Use input formatters for appropriate input restrictions or formatting.
- Use
SingleChildScrollView for forms that may exceed available screen height.
- Use meaningful error messages.
- Avoid collecting unnecessary information.
- Keep the input interface consistent throughout the application.
44. Common TextField Mistakes
- Using a password field without
obscureText.
- Forgetting to dispose controllers.
- Using the wrong keyboard type.
- Using excessively long or unclear labels.
- Creating large fixed-width fields that do not adapt to different screen sizes.
- Using
TextField when TextFormField is more appropriate for a validated form.
- Not handling keyboard overflow in long forms.
- Ignoring focus management in multi-field forms.
- Using client-side input restrictions as a substitute for server-side validation.
45. TextField vs TextEditingController
| Feature |
TextField |
TextEditingController |
| Creates input UI |
Yes |
No |
| Reads current text |
Indirectly through callbacks |
Yes |
| Sets initial text |
Through controller |
Yes |
| Programmatically changes text |
Through controller |
Yes |
| Listens to changes |
onChanged |
addListener() |
46. TextField Important Properties
| Property |
Purpose |
controller |
Controls and reads the text. |
focusNode |
Controls keyboard focus. |
decoration |
Controls labels, hints, borders, icons, and other visual elements. |
keyboardType |
Controls the type of keyboard requested. |
textInputAction |
Controls the keyboard action button. |
textCapitalization |
Controls text capitalization behavior. |
style |
Styles entered text. |
textAlign |
Controls horizontal text alignment. |
readOnly |
Prevents editing while keeping the field enabled. |
enabled |
Enables or disables the field. |
autofocus |
Requests focus automatically. |
obscureText |
Hides sensitive input. |
maxLines |
Controls the maximum number of lines. |
minLines |
Controls the minimum number of lines. |
maxLength |
Limits the number of characters. |
onChanged |
Runs when the user changes the input. |
onSubmitted |
Runs when the user submits the field. |
inputFormatters |
Formats or restricts input. |
47. Mini Project: Student Registration Form
Create a student registration screen using multiple TextFields.
Requirements
- Student Name
- Email Address
- Phone Number
- Age
- Course Name
- Address
- Submit Button
Expected Layout
Student Registration
[ Full Name ]
[ Email Address ]
[ Phone Number ]
[ Age ]
[ Course Name ]
[ Address ]
[ ]
[ ]
[ REGISTER ]
48. Mini Project Code
import 'package:flutter/material.dart';
class StudentRegistration extends StatefulWidget {
const StudentRegistration({super.key});
@override
State createState() =>
_StudentRegistrationState();
}
class _StudentRegistrationState
extends State {
final nameController = TextEditingController();
final emailController = TextEditingController();
final phoneController = TextEditingController();
final ageController = TextEditingController();
final courseController = TextEditingController();
final addressController = TextEditingController();
@override
void dispose() {
nameController.dispose();
emailController.dispose();
phoneController.dispose();
ageController.dispose();
courseController.dispose();
addressController.dispose();
super.dispose();
}
void registerStudent() {
print('Name: ${nameController.text}');
print('Email: ${emailController.text}');
print('Phone: ${phoneController.text}');
print('Age: ${ageController.text}');
print('Course: ${courseController.text}');
print('Address: ${addressController.text}');
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Student Registration'),
),
body: SingleChildScrollView(
padding: const EdgeInsets.all(20),
child: Column(
children: [
TextField(
controller: nameController,
textCapitalization: TextCapitalization.words,
decoration: const InputDecoration(
labelText: 'Full Name',
prefixIcon: Icon(Icons.person_outline),
border: OutlineInputBorder(),
),
),
const SizedBox(height: 16),
TextField(
controller: emailController,
keyboardType: TextInputType.emailAddress,
decoration: const InputDecoration(
labelText: 'Email Address',
prefixIcon: Icon(Icons.email_outlined),
border: OutlineInputBorder(),
),
),
const SizedBox(height: 16),
TextField(
controller: phoneController,
keyboardType: TextInputType.phone,
decoration: const InputDecoration(
labelText: 'Phone Number',
prefixIcon: Icon(Icons.phone_outlined),
border: OutlineInputBorder(),
),
),
const SizedBox(height: 16),
TextField(
controller: ageController,
keyboardType: TextInputType.number,
decoration: const InputDecoration(
labelText: 'Age',
prefixIcon: Icon(Icons.cake_outlined),
border: OutlineInputBorder(),
),
),
const SizedBox(height: 16),
TextField(
controller: courseController,
decoration: const InputDecoration(
labelText: 'Course Name',
prefixIcon: Icon(Icons.school_outlined),
border: OutlineInputBorder(),
),
),
const SizedBox(height: 16),
TextField(
controller: addressController,
maxLines: 4,
decoration: const InputDecoration(
labelText: 'Address',
prefixIcon: Icon(Icons.location_on_outlined),
border: OutlineInputBorder(),
),
),
const SizedBox(height: 24),
SizedBox(
width: double.infinity,
child: FilledButton(
onPressed: registerStudent,
child: const Text('Register'),
),
),
],
),
),
);
}
}
49. Interview Questions
Q1. What is TextField in Flutter?
TextField is a Material Design input widget used to allow users to enter and edit text.
Q2. What is InputDecoration?
InputDecoration controls the visual decoration of a text field, including labels, hints, icons, borders, helper text, and error text.
Q3. What is TextEditingController?
TextEditingController provides access to the current text and allows an application to control the content and selection of a text field.
Q4. What is obscureText?
obscureText hides entered characters and is commonly used for password fields.
Q5. What is the difference between TextField and TextFormField?
TextField is a general-purpose text input widget, while TextFormField wraps a TextField in a FormField and provides integration with Flutter's Form validation and saving mechanisms.
Q6. What is onChanged?
onChanged is a callback that runs when the user changes the text in a field.
Q7. What is onSubmitted?
onSubmitted is called when the user indicates that they have finished editing the field.
Q8. Why should TextEditingController be disposed?
Controllers should be disposed when they are no longer needed so that resources associated with them are released.
Q9. How can you create a multiline TextField?
Set maxLines to a value greater than one, or use maxLines: null when an unrestricted number of lines is appropriate.
Q10. How can you change the keyboard type?
Use the keyboardType property, such as TextInputType.emailAddress, TextInputType.phone, or TextInputType.number.
50. Quick Revision
TextField is used to collect text input.
InputDecoration controls the appearance of the field.
labelText identifies the purpose of the field.
hintText provides an input example or instruction.
prefixIcon displays an icon before the text.
suffixIcon displays an icon after the text.
obscureText is commonly used for passwords.
keyboardType controls the requested keyboard type.
TextEditingController allows text to be read and controlled programmatically.
onChanged responds to user input changes.
onSubmitted responds when editing is submitted.
maxLines can create multiline input.
maxLength can limit input length.
inputFormatters can format or restrict input.
TextFormField is useful when TextField needs to participate in a Form.
- Controllers should be disposed when no longer needed.
51. Official Flutter Resources
52. JustAcademy Flutter Training Resources
53. Key Takeaways
TextField is a fundamental Flutter widget for collecting user input. By combining it with InputDecoration, TextEditingController, callbacks, keyboard configuration, input formatters, focus management, and appropriate styling, developers can create professional input interfaces for forms, search screens, authentication screens, profile pages, and other applications.
When structured form validation is required, use TextFormField with Form and validators. For simple input or search functionality, TextField is often sufficient.