Flutter:一个FocusNode被丢弃后被使用

Seb*_*ien 6 flutter

我在一个有状态小部件中有一个简单的 Flutter 表单,其中包含一堆文本字段来捕获信用卡详细信息。当我显示此表单时,点击第一个字段,在其中输入内容,然后点击第二个字段,焦点不会转移到第二个字段,光标停留在第一个字段,即使两个字段都显示为焦点(边框是两者都可见),当我输入时,它进入第一个字段。在第二个字段中输入内容的唯一方法是长按它,就像我想在其中粘贴一些东西一样。在控制台中,我看到了这个:

[VERBOSE-2:ui_dart_state.cc(199)] Unhandled Exception: A FocusNode was used after being disposed.
Once you have called dispose() on a FocusNode, it can no longer be used.
#0      ChangeNotifier._debugAssertNotDisposed.<anonymous closure> (package:flutter/src/foundation/change_notifier.dart:117:9)
#1      ChangeNotifier._debugAssertNotDisposed (package:flutter/src/foundation/change_notifier.dart:123:6)
#2      ChangeNotifier.notifyListeners (package:flutter/src/foundation/change_notifier.dart:234:12)
#3      FocusNode._notify (package:flutter/src/widgets/focus_manager.dart:1052:5)
#4      FocusManager._applyFocusChange (package:flutter/src/widgets/focus_manager.dart:1800:12)
#5      _rootRun (dart:async/zone.dart:1346:47)
#6      _CustomZone.run (dart:async/zone.dart:1258:19)
#7      _CustomZone.runGuarded (dart:async/zone.dart:1162:7)
Run Code Online (Sandbox Code Playgroud)

问题是没有一个字段具有焦点节点集,因此 Flutter 表单状态内部似乎发生了一些错误。有人见过这个吗?

请注意,对我来说,它发生在网络和移动设备上,但并非始终如一。

这是有问题的表单的代码。

这是一个屏幕截图,说明 2 个字段同时具有焦点,并且光标停留在第一个字段中。当我在键盘上输入内容时,它会指向第一个字段。这是在物理 iPhone 设备上运行的。

在此处输入图片说明

这里是被称为该功能onPressedElevatedButton显示格式如下:

Future<void> _addPaymentMethod(BuildContext context) async {
    await Navigator.push(
      context,
      MaterialPageRoute(
        builder: (context) => Scaffold(
          body: CardForm(),
        ),
      ),
    );
  }
Run Code Online (Sandbox Code Playgroud)

use*_*816 5

我认为问题在于使用 Focus 小部件。

您应该使用 FocusNode 并将此 FocusNode 作为 TextField(您的 CardCvcFormField)的命名参数之一传递。

您可以将侦听器附加到 FocusNode 并获取焦点可见性。

FocusNode _cvcFocusNode;

@override
void initState() {
    super.initState();
    _cvcFocusNode = FocusNode();
    _cvcFocusNode.addListener(_onCvcFormFieldFocusChanged);
}

void _onCvcFormFieldFocusChanged() {
   setState(() => cvcHasFocus = _cvcFocusNode?.hasFocus ?? false);
}

@override
void dispose() {
   _cvcFocusNode?.removeListener(_onCvcFormFieldFocusChanged);
   _cvcFocusNode?.dispose();
   _cvcFocusNode = null;
   super.dispose();
}
Run Code Online (Sandbox Code Playgroud)