Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

FocusScope.nextFocus() unexpectedly skips one or more TextFormFields

Tags:

focus

flutter

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

like image 733
Giorgio Avatar asked Dec 22 '22 16:12

Giorgio


1 Answers

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

like image 192
Ryan Jones Avatar answered Apr 22 '23 17:04

Ryan Jones