5

I would like to have a series of TextFormFields that the user can navigate by pressing "next" on the soft keyboard (or by pressing tab on the hard keyboard, when testing on an emulator). I was expecting the following Flutter app to work:

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'TextFormField Problem Demo',
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key}) : super(key: key);

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Test Homepage'),
      ),
      body: Column(children: <Widget>[
        TextFormField(
          onFieldSubmitted: (_) => FocusScope.of(context).nextFocus(),
          textInputAction: TextInputAction.next,
        ),
        TextFormField(
          onFieldSubmitted: (_) => FocusScope.of(context).nextFocus(),
          textInputAction: TextInputAction.next,
        ),
        TextFormField(
          onFieldSubmitted: (_) => FocusScope.of(context).nextFocus(),
          textInputAction: TextInputAction.next,
        ),
        TextFormField(
          onFieldSubmitted: (_) => FocusScope.of(context).nextFocus(),
          textInputAction: TextInputAction.next,
        ),
        TextFormField(
          textInputAction: TextInputAction.done,
        ),
      ]),
    );
  }
}

... But pressing tab (on DartPad) or pressing "next" (on the soft keyboard of an emulator) jumps to a seemingly random field, instead of jumping to the next one. More specifically, it looks like FocusScope.of(context).nextFocus() "skips" one field (or more fields, sometimes, depending on the run) instead of just going to the next field.

I was assuming that nextFocus() can automatically figure out what is the next focusable widget among the children of my Column, even without explicitly having to specify the focusNode property of my TextFormFields (as seen in another post on StackOverflow). Why is this not the case? Thank you for any input.

I am using Flutter 1.22 on an Android emulator (and on Dartpad).

Giorgio
  • 2,137
  • 3
  • 20
  • 40
  • 1
    I also started facing this issue. Surprisingly, I haven't made any changes to my codebase, just updated Flutter to 1.22 and this started to happen. – rusted brain Oct 09 '20 at 04:14
  • Same here. The update to 1.22 was the only thing that changed in my case too. – Giorgio Oct 09 '20 at 06:20

2 Answers2

9

Flutter 1.22 includes a change to automatically advance the focus when you use textInputAction: TextInputAction.next. However, they didn't update the documentation.

If you specify both onFieldSubmitted and textInputAction, it does not work because it has the effect of calling nextFocus twice. So, the Flutter change was a breaking change.

You don't need to specify the onEditingComplete callback and handle it manually. Just TextInputAction.next is enough by itself.

The relevant Flutter change is here. Also, some discussion here.

Note in the description of the Flutter change it says, "Focus will be moved automatically if onEditingComplete is not specified, but must by moved manually if onEditingComplete is specified."

Ryan Jones
  • 236
  • 2
  • 5
  • Thank you for the detailed answer and for the links. Trying to only set `textInputAction` on DartPad (currently running Flutter 1.23) unfortunately still shows the same problem. I will try the same on an Android emulator as soon as I can. Moreover, as stated in the question, the number of fields that are "skipped" is unfortunately not just 1, but a seemingly random number: could it be that there is another, different problem from the one you are mentioning? – Giorgio Oct 27 '20 at 18:01
  • @Giorgio I tested the solution on both Android and iOS emulators, and it works for me. According to the Flutter engineer, it will skip just 1 field when you specify both. For example, see here: https://github.com/flutter/flutter/issues/68571#issuecomment-716835454 And here: https://github.com/flutter/flutter/issues/68571#issuecomment-716867536 – Ryan Jones Oct 27 '20 at 18:39
  • 1
    He did say "roughly equivalent to calling nextFocus() twice", so maybe roughly is a clue that it won't always behave the same way. Just a guess, I haven't checked the Flutter source code. – Ryan Jones Oct 27 '20 at 18:46
  • Thaaaank you for the hint! – ruclip Feb 01 '21 at 10:22
2

onEditingComplete() should work in your case, not sure why onSubmitted() not working it should be working, might be a defect on latest version

Column(children: <Widget>[
        TextFormField(
          onEditingComplete: () => FocusScope.of(context).nextFocus(),
          textInputAction: TextInputAction.next,
        ),
        TextFormField(
          onEditingComplete: () => FocusScope.of(context).nextFocus(),
          textInputAction: TextInputAction.next,
        ),
        TextFormField(
          onEditingComplete: () => FocusScope.of(context).nextFocus(),
          textInputAction: TextInputAction.next,
        ),
        TextFormField(
          onEditingComplete: () => FocusScope.of(context).nextFocus(),
          textInputAction: TextInputAction.next,
        ),
        TextFormField(
          textInputAction: TextInputAction.done,
        ),
      ]),
Jitesh Mohite
  • 31,138
  • 12
  • 157
  • 147
  • Thank you for your answer. For some strange reason, `onEditingComplete` solves my problem on the Android emulator but not on DartPad. I'm currently double-checking if there might be some other mistake I have made.. – Giorgio Oct 06 '20 at 14:13
  • I don't think it will work on the dart pad, there is an issue with the keyboard there, just run on a real device if works. The problem will be solved. if works, accept the answer so that others can find it useful. – Jitesh Mohite Oct 06 '20 at 15:53
  • Thank you. Are you sure there is an issue with DartPad's keyboard? Would you mind adding a link to where you found this problem (or to explain the problem)? If there's an issue with DartPad then I can very gladly mark your answer as accepted, but I should first make sure that there is such an issue, if you don't mind. – Giorgio Oct 06 '20 at 19:55
  • On DartPad when I click it even not open the keyboard sometimes, I cannot provide you official docs for it. But I think if it's working on all real devices then there is no issue. It's an online emulator kind of web portal, so don't just depend on it. – Jitesh Mohite Oct 07 '20 at 03:41