当文本字段在 Flutter 中退出焦点(模糊)时,如何捕获事件?

Che*_*ong 29 flutter flutter-textformfield

我查看 TextFormField,这里的字段不是我需要的:

  • onChanged(在按下每个键后调用,我需要当用户已经完成并退出 TextFormField 焦点时)
  • onEditingComplete(在用户按下完成键或类似键后调用,但用户可以退出 TextFormField 焦点而不点击这些按钮)
  • onSave(在调用后调用form.save()。但我需要在用户完成编辑后执行此操作,以让用户知道该应用程序会“自动更正”用户输入的内容)
  • validator(也曾呼吁过form.validate(),就在之前form.save()。不是我需要的)

我需要当用户退出焦点(关闭键盘或点击另一个文本字段)时,我进行处理,让用户看到他们的输入正在被调整和处理为“正确的”。我怎样才能捕捉到这样的事件?

KuK*_*uKu 45

通过使用FocusNode类,您可以添加焦点侦听器并可以捕获焦点更改。

通过使用Focus类,您只需包装 TextField 并添加 onFocusChange 参数即可。

[解决方案1]

  • 添加定义 FocusNode 实例
FocusNode focusNode = FocusNode();
Run Code Online (Sandbox Code Playgroud)
  • 在initState处添加FocusNode的监听器。
focusNode.addListener(() {
      print('1:  ${focusNode.hasFocus}');
    });
Run Code Online (Sandbox Code Playgroud)
  • 将 FocusNode 实例添加到 TextField 的 focusNode 参数。
TextField(
      focusNode: focusNode,
    )
Run Code Online (Sandbox Code Playgroud)

[解决方案2]

  • 通过焦点小部件包裹 TextField
Focus(
  child: TextField(),
  onFocusChange: (hasFocus) {
    print('2:  $hasFocus');
  },
)
Run Code Online (Sandbox Code Playgroud)

[示例完整代码]

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

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

class _MyHomePageState extends State<MyHomePage> {
  FocusNode focusNode = FocusNode();
  @override
  void initState() {
    super.initState();
    focusNode.addListener(() {
      print(focusNode.hasFocus);
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: _buildBody(),
    );
  }

  Widget _buildBody() {
    return TextField(
      focusNode: focusNode,
    );
  }
}


Run Code Online (Sandbox Code Playgroud)

  • 欧。我只听说过第一个解决方案,但从未听说过第二个。我认为第二种解决方案最适合我。谢谢!! (4认同)