FocusScope.nextFocus() 意外跳过一个或多个 TextFormField

FocusScope.nextFocus() unexpectedly skips one or more TextFormFields

我想要一系列 TextFormField,用户可以通过按软键盘上的“下一步”(或在模拟器上测试时按硬键盘上的 Tab)来导航。我期待以下 Flutter 应用程序能够运行:

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,
        ),
      ]),
    );
  }
}

... 但是按tab键(在DartPad上)或按“next”(在模拟器的软键盘上)跳转到了一个看似随机的字段,而不是跳转到下一个。更具体地说,它看起来 FocusScope.of(context).nextFocus()“跳过”一个字段(或多个字段,有时取决于 运行),而不是仅仅转到下一个字段。

我假设 nextFocus() 可以自动找出我 Column 的子项中的下一个可聚焦小部件,即使无需明确指定 focusNode 属性 我的 TextFormFields(如 Whosebug 上的 所示)。为什么不是这样呢?感谢您的任何意见。

我在 Android 模拟器(和 Dartpad)上使用 Flutter 1.22。

onEditingComplete() 应该适用于您的情况,不确定为什么 onSubmitted() 不起作用它应该可以工作,可能是最新版本的缺陷

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,
        ),
      ]),

Flutter 1.22 包含一项更改,可在您使用 textInputAction 时自动推进焦点:TextInputAction.next。但是,他们没有更新文档。

如果同时指定onFieldSubmitted和textInputAction,则不起作用,因为它具有调用nextFocus两次的效果。所以,Flutter 的改变是一个突破性的改变。

您无需指定onEditingComplete 回调并手动处理。 TextInputAction.next 本身就足够了。

Flutter 的相关变化是here. Also, some discussion here

在 Flutter 更改的描述中请注意,“如果未指定 onEditingComplete,焦点将自动移动,但必须 如果指定了 onEditingComplete,则手动移动。