I am new to Flutter.
I am building a form with multiple text inputs using following widgets: Form, TextFormField. The keyboard that appears doesn't show "next" (which should shift the focus to next field) field action instead it is "done" action (which hides the keyborad).
I looked for any hints in official docs, found nothing directly that can be done. I although landed on FocusNode(cookbook, api doc). It provides with mechanism to shift focus by some button or any other action on app, but I want it to be in keyboard.
Using onFieldSubmitted callback to request the focus node of the next field. For TextFormField use can use onFieldSubmitted.
Next, we need to check to see if the current FocusNode has the “primary focus.” If it doesn't, we call unfocus() on the current node to remove focus and trigger the keyboard to dismiss. If you attempt to unfocus() a node that currently has the primary focus, Flutter will throw an exception.
Screenshot:
Just use:
textInputAction: TextInputAction.next
: To move the cursor to the next field.
textInputAction: TextInputAction.done
: To close the keyboard.
@override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
children: <Widget>[
TextField(
decoration: InputDecoration(hintText: 'TextField A'),
textInputAction: TextInputAction.next, // Moves focus to next.
),
TextField(
decoration: InputDecoration(hintText: 'TextField B'),
textInputAction: TextInputAction.next, // Moves focus to next.
),
TextField(
decoration: InputDecoration(hintText: 'TextField C'),
textInputAction: TextInputAction.done, // Hides the keyboard.
),
],
),
);
}
Found a way to achieve it.
Displaying Next Icon instead of Done - setting textInputAction
parameter to TextInputAction.next
Using onFieldSubmitted
callback to request focus node of next field.
class FormWidget extends StatelessWidget{
final focus = FocusNode();
@override
Widget build(BuildContext context) {
return Form(
child: SingleChildScrollView(
padding: EdgeInsets.symmetric(horizontal: 16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
TextFormField(
textInputAction: TextInputAction.next,
autofocus: true,
decoration: InputDecoration(labelText: "Input 1"),
onFieldSubmitted: (v){
FocusScope.of(context).requestFocus(focus);
},
),
TextFormField(
focusNode: focus,
decoration: InputDecoration(labelText: "Input 2"),
),
],
),
),
);
}
}
Edit: As stated in the documentation (flutter.io/docs/cookbook/forms/focus), - we also need to manage FocusNode lifecycle. So, init FocusNode in the init() method and dispose in dispose() of the parent Widget. - @AntonDerevyanko
Update: The same can be achieved without FocusNode
and FocusScopeNode
, by simply calling FocusScope.of(context).nextFocus()
, take a look at CopsOnRoad solution on how to do that. For more info check doc.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With