Flutter’s TextField
widget is a versatile tool for accepting user input. However, the types of input users can enter vary widely—from simple text and numbers to emails, passwords, and more. Properly handling different text input types enhances user experience, ensures data integrity, and optimizes keyboard layouts. This article explores how to effectively manage different text input types using Flutter’s TextField
widget.
Understanding the TextField
Widget
The TextField
widget in Flutter is used to capture text input from the user. It provides several properties to configure the input method, styling, and validation. A key property for handling different input types is keyboardType
.
Why Handle Different Text Input Types?
- Improved User Experience: Tailored keyboard layouts for specific input types make data entry faster and more accurate.
- Data Validation: Enforcing specific input types ensures data conforms to expected formats.
- Accessibility: Correct input types aid assistive technologies in understanding and processing user input.
Setting the keyboardType
Property
The keyboardType
property in TextField
is of type TextInputType
. Here’s how to use it for different input types:
1. Basic Text Input
For general text input, use TextInputType.text
. This displays a standard keyboard layout.
TextField(
keyboardType: TextInputType.text,
decoration: InputDecoration(
labelText: 'Enter text',
),
)
2. Numeric Input
To display a numeric keypad, use TextInputType.number
. This is ideal for accepting numerical data like ages, quantities, or IDs.
TextField(
keyboardType: TextInputType.number,
decoration: InputDecoration(
labelText: 'Enter number',
),
)
3. Decimal Input
For input that requires decimal numbers, use TextInputType.numberWithOptions(decimal: true)
. This provides a numeric keypad with a decimal point.
TextField(
keyboardType: const TextInputType.numberWithOptions(decimal: true),
decoration: InputDecoration(
labelText: 'Enter decimal number',
),
)
4. Phone Number Input
Use TextInputType.phone
for accepting phone numbers. This displays a numeric keypad optimized for phone number entry, often including symbols like *
and #
.
TextField(
keyboardType: TextInputType.phone,
decoration: InputDecoration(
labelText: 'Enter phone number',
),
)
5. Email Address Input
For email addresses, use TextInputType.emailAddress
. This presents a standard keyboard layout but typically suggests email addresses from the user’s device.
TextField(
keyboardType: TextInputType.emailAddress,
decoration: InputDecoration(
labelText: 'Enter email address',
),
)
6. Date and Time Input
For entering dates and times, consider using a combination of showDatePicker
or showTimePicker
with text input fields. While there isn’t a specific TextInputType
for dates and times, you can use TextInputType.datetime
to assist with formatting and validation after input.
import 'package:flutter/material.dart';
class DateTimeInput extends StatefulWidget {
@override
_DateTimeInputState createState() => _DateTimeInputState();
}
class _DateTimeInputState extends State {
TextEditingController dateController = TextEditingController();
TextEditingController timeController = TextEditingController();
Future _selectDate(BuildContext context) async {
final DateTime? picked = await showDatePicker(
context: context,
initialDate: DateTime.now(),
firstDate: DateTime(2000),
lastDate: DateTime(2025),
);
if (picked != null) {
setState(() {
dateController.text = "${picked.toLocal()}".split(' ')[0];
});
}
}
Future _selectTime(BuildContext context) async {
final TimeOfDay? picked = await showTimePicker(
context: context,
initialTime: TimeOfDay.now(),
);
if (picked != null) {
setState(() {
timeController.text = picked.format(context);
});
}
}
@override
Widget build(BuildContext context) {
return Column(
children: [
TextField(
controller: dateController,
keyboardType: TextInputType.datetime,
decoration: InputDecoration(
labelText: 'Select Date',
suffixIcon: IconButton(
icon: Icon(Icons.calendar_today),
onPressed: () => _selectDate(context),
),
),
readOnly: true,
onTap: () => _selectDate(context),
),
TextField(
controller: timeController,
keyboardType: TextInputType.datetime,
decoration: InputDecoration(
labelText: 'Select Time',
suffixIcon: IconButton(
icon: Icon(Icons.access_time),
onPressed: () => _selectTime(context),
),
),
readOnly: true,
onTap: () => _selectTime(context),
),
],
);
}
}
7. URL Input
For URLs, use TextInputType.url
. This configures the keyboard for easy URL entry and might suggest previously entered URLs.
TextField(
keyboardType: TextInputType.url,
decoration: InputDecoration(
labelText: 'Enter URL',
),
)
Masking and Formatting Text Input
For more complex formatting requirements, such as phone numbers or currency values, consider using input formatters.
Using Input Formatters
Input formatters allow you to transform user input as it’s being typed. You can create custom formatters or use existing ones from packages like flutter_masked_text2
or mask_text_input_formatter
.
Here’s an example of using an input formatter for phone number masking:
import 'package:flutter/material.dart';
import 'package:mask_text_input_formatter/mask_text_input_formatter.dart';
class PhoneNumberInput extends StatelessWidget {
final maskFormatter = MaskTextInputFormatter(
mask: '+# (###) ###-##-##',
filter: { "#": RegExp(r'[0-9]') },
type: MaskAutoCompletionType.lazy
);
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.all(16.0),
child: TextField(
keyboardType: TextInputType.phone,
inputFormatters: [maskFormatter],
decoration: InputDecoration(
labelText: 'Phone Number',
hintText: '+1 (555) 555-5555',
border: OutlineInputBorder(),
),
),
);
}
}
Password Input
For password fields, set obscureText: true
to hide the entered text. Combine this with TextInputType.visiblePassword
or TextInputType.text
for the keyboard.
TextField(
keyboardType: TextInputType.visiblePassword,
obscureText: true,
decoration: InputDecoration(
labelText: 'Enter password',
),
)
Custom Keyboard Layouts
In some advanced cases, you may need a completely custom keyboard layout. While Flutter doesn’t natively support custom keyboard layouts in TextField
, you can build one using a combination of custom widgets and overlaying them on the screen.
Validation
Validating input ensures data integrity. You can use the validator
property in TextField
to define validation rules.
TextFormField(
keyboardType: TextInputType.emailAddress,
decoration: InputDecoration(
labelText: 'Email',
),
validator: (value) {
if (value == null || value.isEmpty) {
return 'Please enter your email';
}
if (!value.contains('@')) {
return 'Please enter a valid email';
}
return null;
},
)
Conclusion
Handling different text input types in Flutter’s TextField
enhances the user experience, ensures data integrity, and improves accessibility. By using the appropriate keyboardType
and combining it with input formatters and validation, you can effectively manage various input scenarios and build robust, user-friendly applications.