Flutter / UI Elements / Text Field
Text Field
-
Basics
TextField() widget is an input element. It enables the user to enter the data 1.Syntax
TextField( ) Complete code
import 'package:flutter/material.dart'; void main() => runApp(MyApp()); class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( home: MyHomePage(), ); } } class MyHomePage extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( body: TextField() ); } } Note that TextField() widget is used in the body parameter of above code -
2. Where to use it ?
1. Inside a Column:
Column( mainAxisAlignment: MainAxisAlignment.center, children: [ TextField( decoration: InputDecoration( labelText: 'Enter your username', hintText: 'Username', ), ), // Add more widgets below the TextField if needed ], ) 2. Inside a Row:
Row( mainAxisAlignment: MainAxisAlignment.center, children: [ Expanded( child: TextField( decoration: InputDecoration( labelText: 'Enter your email', hintText: 'Email', ), ), ), // Add more widgets after the TextField if needed ], ) 3. Inside a Container with Padding:
Container( padding: EdgeInsets.all(16.0), child: TextField( decoration: InputDecoration( labelText: 'Enter your password', hintText: 'Password', ), ), ) 4. Inside a ListView:
ListView( padding: EdgeInsets.all(16.0), children: [ TextField( decoration: InputDecoration( labelText: 'Enter your address', hintText: 'Address', ), ), // Add more widgets after the TextField if needed ], ) -
3. Reusable Widget
Option 1: Using widget
import 'package:flutter/material.dart'; void main() { runApp(MyApp()); } // the root widget of our application class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( home: Scaffold( appBar: AppBar( title: Text("Exploring Widgets"), ), body: myWidget(), ), ); } } // This is where we will play with the widget Widget myWidget() { return TextField( decoration: InputDecoration( border: InputBorder.none, hintText: 'Write something here' ), ); } 2. Option 2: custom widget
Create custom class
usageimport 'package:flutter/material.dart'; class CustomTextField extends StatelessWidget { final TextEditingController controller; final String hintText; final TextInputType keyboardType; final bool obscureText; const CustomTextField({ Key? key, required this.controller, required this.hintText, this.keyboardType = TextInputType.text, this.obscureText = false, }) : super(key: key); @override Widget build(BuildContext context) { return TextFormField( controller: controller, keyboardType: keyboardType, obscureText: obscureText, decoration: InputDecoration( hintText: hintText, border: OutlineInputBorder(), ), ); } } class MyWidget extends StatelessWidget { final TextEditingController _emailController = TextEditingController(); final TextEditingController _passwordController = TextEditingController(); @override Widget build(BuildContext context) { return Scaffold( body: Padding( padding: EdgeInsets.all(20.0), child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ CustomTextField( controller: _emailController, hintText: 'Enter your email', keyboardType: TextInputType.emailAddress, ), SizedBox(height: 20.0), CustomTextField( controller: _passwordController, hintText: 'Enter your password', obscureText: true, ), SizedBox(height: 20.0), ElevatedButton( onPressed: () { // Access text using _emailController.text and _passwordController.text }, child: Text('Submit'), ), ], ), ), ); } } -
4. Properties
1. controller:
Allows you to control the text and selection of the TextField widget. You can use a 'TextEditingController()' to manipulate its content programmatically.
GET : read the data from inputbox
class _TextFormState extends State { TextEditingController textController = TextEditingController(); String displayText = ""; @override Widget build(BuildContext context) { return Column( children: [ TextField( controller: textController, maxLines: null, ), ElevatedButton(onPressed: (){ setState(() { displayText = textController.text; }); }, child: Text("Show Text")), Text(displayText,style: TextStyle(fontSize: 20),) ], ); } } SET: Pre-populating text into inputbox
2. decoration:TextEditingController textController = TextEditingController(text: "Initial Text"); @override Widget build(BuildContext context) { return Center( child: TextField( controller: textController, ), ); } Defines the appearance of the TextField, including borders, labels, hints, icons, and more. It takes an InputDecoration object.
3. textAlign:Sets the alignment of the text within the TextField. Options include TextAlign.left, TextAlign.center, TextAlign.right, etc.
4. keyboardType:Specifies the type of keyboard to display, such as text, number, email, URL, etc. (TextInputType enum)
5. textCapitalization:TextField( keyboardType: TextInputType.number, ) Controls the capitalization behavior of the input text. Options include TextCapitalization.none, TextCapitalization.words, TextCapitalization.sentences, etc.
6. readOnly:When set to true, prevents editing the content in the TextField.
7. maxLines:Sets the maximum number of lines the TextField can occupy.
8. onChanged:Callback function triggered when the text input changes. It allows you to handle text changes dynamically.
9. onSubmitted:Callback function called when the user submits the text (e.g., pressing enter on the keyboard).
10. enabled:Allows enabling or disabling the TextField. When set to false, it's disabled and won't receive focus or user input.
TextField( controller: myController, decoration: InputDecoration( labelText: 'Enter your name', hintText: 'John Doe', prefixIcon: Icon(Icons.person), border: OutlineInputBorder(), ), textAlign: TextAlign.center, keyboardType: TextInputType.text, textCapitalization: TextCapitalization.words, readOnly: false, maxLines: 1, onChanged: (value) { // Handle text changes }, onSubmitted: (value) { // Handle submitted text }, enabled: true, ) -
5. Text field Decoration
Styling a text field
Changing text colorTextField( decoration: InputDecoration( fillColor: Colors.grey.shade100, filled: true, hintText: 'Email', border: OutlineInputBorder( borderRadius: BorderRadius.circular(10), ), ), ) TextField( cursorColor: Colors.black, style: TextStyle( color: Colors.white ), decoration: InputDecoration( filled: true, fillColor: Colors.blueAccent, border: OutlineInputBorder( borderSide: BorderSide.none, borderRadius: BorderRadius.circular(50) ), ), ) cursorColor property Adding hint text
Adding multi-line supportTextField( decoration: InputDecoration( hintStyle: TextStyle(color: Colors.blue), hintText: "Enter your name" ), )
1. labelText:TextField( maxLines: 5, ), Adds a label above the TextField when it's not focused.
2. hintText:Provides a hint text that appears when the TextField is empty.
3. prefixIcon and suffixIcon:Allows adding icons before and after the input text.
4. border:Sets the border around the TextField. Options include OutlineInputBorder, UnderlineInputBorder, or you can create a custom InputBorder.
5. enabledBorder, focusedBorder, errorBorder, disabledBorder:Customize the border appearance in different states (enabled, focused, error, disabled).
6. filled and fillColor:Specifies whether the TextField is filled and the color to fill when it's enabled.
7. errorText and errorStyle:Displays error text and allows styling the error message.
TextField( decoration: InputDecoration( labelText: 'Enter your username', hintText: 'Username', prefixIcon: Icon(Icons.person), suffixIcon: Icon(Icons.check_circle), border: OutlineInputBorder(), enabledBorder: OutlineInputBorder( borderSide: BorderSide(color: Colors.grey), borderRadius: BorderRadius.circular(10.0), ), focusedBorder: OutlineInputBorder( borderSide: BorderSide(color: Colors.blue), borderRadius: BorderRadius.circular(10.0), ), errorBorder: OutlineInputBorder( borderSide: BorderSide(color: Colors.red), borderRadius: BorderRadius.circular(10.0), ), filled: true, fillColor: Colors.grey[200], errorText: 'Invalid username', errorStyle: TextStyle(color: Colors.red), ), ) class _LoginFormState extends State { TextEditingController textController = TextEditingController(); RegExp digitValidator = RegExp("[0-9]+"); bool isANumber = true; @override Widget build(BuildContext context) { return Center( child: TextField( onChanged: (inputValue){ if(inputValue.isEmpty || digitValidator.hasMatch(inputValue)){ setValidator(true); } else{ setValidator(false); } }, decoration: InputDecoration( errorText: isANumber ? null : "Please enter a number" ), ), ); } void setValidator(valid){ setState(() { isANumber = valid; }); } }
Restricting the number of charactersTextField( onChanged: (inputValue){ if(inputValue.isEmpty || digitValidator.hasMatch(inputValue)){ setValidator(true); } else{ setValidator(false); } }, decoration: InputDecoration( errorText: isANumber ? null : "Please enter a number", errorStyle: TextStyle(color: Colors.purpleAccent), focusedErrorBorder: UnderlineInputBorder(borderSide: BorderSide(color: Colors.purpleAccent)), errorBorder: UnderlineInputBorder(borderSide: BorderSide(color: Colors.purpleAccent)) ), )
Restricting and allowing input valuesTextField( maxLength: 2, ) TextField( inputFormatters: [FilteringTextInputFormatter.deny(RegExp("[0-9]+"))], ) -
6. Password field
TextField( obscureText: true, decoration: InputDecoration( fillColor: Colors.grey.shade100, filled: true, hintText: 'Password', border: OutlineInputBorder( borderRadius: BorderRadius.circular(10), ), ), ) obscureText: true,