How to shift focus to next textfield in flutter?

前端 未结 7 2098
甜味超标
甜味超标 2020-12-04 23:36

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\" (w

相关标签:
7条回答
  • 2020-12-04 23:52

    Screenshot:


    You can do that without using FocusNode or FocusScopeNode.

    @override
    Widget build(BuildContext context) {
      final node = FocusScope.of(context);
      return Scaffold(
        body: Column(
          children: <Widget>[
            TextField(
              decoration: InputDecoration(hintText: 'TextField A'),
              textInputAction: TextInputAction.next,
              onEditingComplete: () => node.nextFocus(), // Move focus to next
            ),
            TextField(
              decoration: InputDecoration(hintText: 'TextField B'),
              textInputAction: TextInputAction.next,
              onEditingComplete: () => node.nextFocus(), // Move focus to next
            ),
            TextField(
              decoration: InputDecoration(hintText: 'TextField C'),
              textInputAction: TextInputAction.done,
              onSubmitted: (_) => node.unfocus(), // Submit and hide keyboard
            ),
          ],
        ),
      );
    }
    
    0 讨论(0)
  • 2020-12-04 23:55

    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.

    0 讨论(0)
  • 2020-12-05 00:05

    I used onSubmitted instead of onFieldSubmitted

    Example code

          TextField(
                    textInputAction: TextInputAction.next,
                    onSubmitted: (_) => FocusScope.of(context).nextFocus(),
                    controller: _phoneController,
                    decoration: const InputDecoration(
                      labelText: 'Phone number',
                    ),
                    style: TextStyle(fontSize: 16.0, color: Colors.white),
                  ),
    
    0 讨论(0)
  • 2020-12-05 00:12

    This is additional steps to CopsOnRoad answer since it doesn't work in more complex UI when there are focusable widgets in between text fields, for example:

    • when password field has a clickable toggle icon
    • when there is a button(or some other focusable widget) between fields...

    The solution here is to keep calling 'nextFocus()' until 'EditableText' is Found

       @override
        Widget build(BuildContext context) {
          return Scaffold(
            body: Column(
              children: <Widget>[
                TextField(
                  decoration: InputDecoration(hintText: "TextField A"),
                  textInputAction: textInputAction1,
                  onSubmitted: (_) => context.nextEditableTextFocus(), // move focus to next
                ),
                TextField(
                  decoration: InputDecoration(hintText: "TextField B"),
                  textInputAction: textInputAction2,
                  onSubmitted: (_) => context.nextEditableTextFocus(), // move focus to next
                ),
                MaterialButton(
                 onPressed: () {},
                 color: Colors.amber,
                ),
                TextField(
                  decoration: InputDecoration(hintText: "TextField C"),
                  textInputAction: textInputAction3,
                  onSubmitted: (_) => FocusScope.of(context).unfocus(), // submit and hide keyboard
                ),
              ],
            ),
          );
        }
    

    where the extension method is:

    extension Utility on BuildContext {
      void nextEditableTextFocus() {
        do {
          FocusScope.of(this).nextFocus();
        } while (FocusScope.of(this).focusedChild.context.widget is! EditableText);
      }
    }
    
    0 讨论(0)
  • 2020-12-05 00:12

    For me this worked it moves to next input on entering first digit

    Row(
                      children: <Widget>[
                        Expanded(
                          child: TextFormField(
                            textInputAction: TextInputAction.next,
                            onChanged: (_) => FocusScope.of(context).nextFocus(),
                              controller:c1 ,)
                        ),
                        SizedBox(
                          width: 20.0,
                        ),
                        Expanded(
                          child: TextFormField(
                            textInputAction: TextInputAction.next,
                            onChanged: (_) => FocusScope.of(context).nextFocus(),
                              controller:c2 ,),
                        ),
                        SizedBox(
                          width: 20.0,
                        ),
                        Expanded(
                          child: TextFormField(
                              controller:c3 ,
                            textInputAction: TextInputAction.next,
                            onChanged: (_) => FocusScope.of(context).nextFocus(),),
                        ),
                        SizedBox(
                          width: 20.0,
                        ),
                        Expanded(
                          child: TextFormField(
                              controller:c4 ,
                            textInputAction: TextInputAction.next,
                            onChanged: (_) => FocusScope.of(context).nextFocus(),),
                        ),
                        SizedBox(
                          width: 20.0,
                        ),
                        Expanded(
                          child: TextFormField(
    
                              controller:c5 ,
                            textInputAction: TextInputAction.next,
                            onChanged: (_) => FocusScope.of(context).nextFocus(),),
                        ),
                        SizedBox(
                          width: 20.0,
                        ),
                        Expanded(
                          child: TextFormField(
                              controller:c6 ,
                            textInputAction: TextInputAction.next,
                            onChanged: (_) => FocusScope.of(context).unfocus(),
                              ),
                        )
                      ],
                    )
    
    0 讨论(0)
  • 2020-12-05 00:12

    You can use this helper function to focus the next text field :

    void focusNextTextField(BuildContext context) {
      do {
        var foundFocusNode = FocusScope.of(context).nextFocus();
        if (!foundFocusNode) return;
      } while (FocusScope.of(context).focusedChild.context.widget is! EditableText);
    }
    
    0 讨论(0)
提交回复
热议问题