Search code examples
flutterdartflutter-layoutfocustextfield

How to shift focus to the next TextField in Flutter?


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.


Solution

  • Found a way to achieve it.

    1. Displaying Next Icon instead of Done - setting textInputAction parameter to TextInputAction.next

    2. 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.