如何检测何时在 Flutter 中选择了 TextField?

How to detect when a TextField is selected in Flutter?

我有一个 Flutter TextField,当该字段被选中时它会被软键盘覆盖。当显示键盘时,我需要将字段向上滚动并移开。这是一个非常常见的问题,.

中提供了解决方案

我想我已经弄清楚了 ScrollController 部分,但是如何检测何时选择了 TextField?似乎没有任何事件方法(例如 onFocus()、onSelected()、onTap() 等)。

我尝试将 TextField 包装在 GestureDetector 中,但这也不起作用——显然事件从未被捕获。

new GestureDetector(
  child: new TextField(
    decoration: const InputDecoration(labelText: 'City'),
  ),
  onTap: () => print('Text Selected'),
),

这是一个非常基本的要求,我知道一定有一个简单的解决方案。

我想你正在寻找 FocusNode

要监听焦点变化,您可以将监听器添加到 FocusNode 并将 focusNode 指定为 TextField

示例:

class TextFieldFocus extends StatefulWidget {
  @override
  _TextFieldFocusState createState() => _TextFieldFocusState();
}

class _TextFieldFocusState extends State<TextFieldFocus> {
  FocusNode _focus = FocusNode();

  TextEditingController _controller = TextEditingController();

  @override
  void initState() {
    super.initState();
    _focus.addListener(_onFocusChange);
  }

  @override
  void dispose() {
    super.dispose();
    _focus.removeListener(_onFocusChange);
    _focus.dispose();
  }

  void _onFocusChange() {
    debugPrint("Focus: ${_focus.hasFocus.toString()}");
  }
  
  @override
  Widget build(BuildContext context) {
    return new Container(
      color: Colors.white,
      child: new TextField(
        focusNode: _focus,
      ),
    );
  }
}

This 要点表示如何确保焦点节点在 ui.

上可见

希望对您有所帮助!

最简单最简单的解决方案是在 TextField 上添加 onTap 方法。

TextField(
  onTap: () {
    print('Editing stated $widget');
  },
)

要获得有关焦点事件的通知,您可以避免手动管理小部件的状态,方法是使用实​​用程序 类 FocusScopeFocus

来自文档 (https://api.flutter.dev/flutter/widgets/FocusNode-class.html):

Please see the Focus and FocusScope widgets, which are utility widgets that manage their own FocusNodes and FocusScopeNodes, respectively. If they aren't appropriate, FocusNodes can be managed directly.

这是一个简单的例子:

FocusScope(
  child: Focus(
    onFocusChange: (focus) => print("focus: $focus"),
    child: TextField(
      decoration: const InputDecoration(labelText: 'City'),
    )
  )
)

只需使用TextFieldonTap功能即可。

TextField(
  onTap: () {
    // Your code.
  },
);

如果出于某些目的需要禁用您的文本字段,还有另一种方法,例如我的。对于这种情况,您可以像这样用 InkWell 包裹您的 textField,

InkWell(
  onTap: () {
    print('clicked');
  },
  child: TextField(
    enabled: false,
  ),
);