Flutter – Managing Form Input Focus
In this article, we will see how we can manage Form Input Focus in Flutter. When a TextField widget is selected and is taking input, it is said to have focus. Users may shift focus to a TextField simply by tapping on it.
Suppose we have a messaging application, when the user navigates to the messaging screen, we can set the focus to the TextField where we type the message. This allows our user to begin typing the message as soon as the screen is visible, without manually tapping on the TextField.
Note: We need to manage the lifecycle of focus nodes using a State object as focus nodes are long-lived objects.
We can focus on the TextField as soon as it’s visible using the autofocus property. It has the following syntax:
Syntax:
TextField( autofocus: true, );
We can also focus on a text field on a button tap using focusNode property. It involves three steps:
Step 1: Create a FocusNode.
The following syntax can be used to focus node:
Syntax:
FocusNode gfgFocusNode; @override void initState() { super.initState(); gfgFocusNode = FocusNode();
Step 2: Passing the FocusNode to the TextField.
You can use the @override decorator with the Widget builder to pass the focus node as shown below.
@override Widget build(BuildContext context) { return TextField( focusNode: gfgFocusNode, ); }
Step 3: Use requestFocus() to give the focus to the TextField on button tap.
The requestFocous() method can be used to focus on the TextField when the form is tapped as shown below:
onPressed: () => gfgFocusNode.requestFocus()
Example:
Dart
import 'package:flutter/material.dart' ; void main() { runApp(MyApp()); } class MyApp extends StatelessWidget { // This widget is the root of your application. @override Widget build(BuildContext context) { return MaterialApp( home: Scaffold( appBar: AppBar( title: Text( "GFG | Input Focus" ), backgroundColor: Color.fromRGBO(15, 157, 88, 1), ), body: InputForm(), ), ); } } // Defining a custom Form widget class InputForm extends StatefulWidget { @override _InputFormState createState() => _InputFormState(); } // Defining a corresponding State class // This class holds data related to the InputForm class _InputFormState extends State<InputForm> { // Defining the focus node FocusNode focusNode1; FocusNode focusNode2; @override void initState() { super.initState(); // To manage the lifecycle, creating focus nodes in // the initState method focusNode1 = FocusNode(); focusNode2 = FocusNode(); } // Called when the object is removed // from the tree permanently @override void dispose() { // Clean up the focus nodes // when the form is disposed focusNode1.dispose(); focusNode2.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return Padding( padding: const EdgeInsets.all(20.0), child: Column( children: [ TextField( // The first TextField is focused // on as soon as the app starts autofocus: true , focusNode: focusNode1, decoration: InputDecoration( labelText: "First" , labelStyle: TextStyle(fontSize: 25.0), ), ), SizedBox( height: 50.0, ), TextField( // The second TextField is focused // on when a user taps the second button focusNode: focusNode2, decoration: InputDecoration( labelText: "Second" , labelStyle: TextStyle(fontSize: 25.0), ), ), SizedBox( height: 150.0, ), RaisedButton( onPressed: () { // When the button is pressed, // give focus to the first TextField // using focusNode1. focusNode1.requestFocus(); }, color: Color.fromRGBO(15, 157, 88, 1), textColor: Colors.white, child: Text( "Focus on First Text Field" , style: TextStyle( color: Colors.white, ), ), ), SizedBox( height: 50.0, ), RaisedButton( onPressed: () { // When the button is pressed, // give focus to the second // TextField using focusNode2. focusNode2.requestFocus(); }, color: Color.fromRGBO(15, 157, 88, 1), child: Text( "Focus on Second Text Field" , style: TextStyle( color: Colors.white, ), ), ) ], ), ); } } |
Output: