焦点更改时的 TextFormField 验证

mrp*_*490 5 flutter

我正在使用一个表单和一些 TextFormFields。我可以验证用户输入如下:

final _form = GlobalKey<FormState>();

void saveForm(){

_form.currentState.validate()

}

//saveForm runs when a save button is pressed.
Run Code Online (Sandbox Code Playgroud)

我想知道是否可以在 TextField 失去焦点时为其运行验证功能。(我不想通过单击按钮来验证输入,相反,我想在用户更改 TextField 时运行验证功能.)

San*_*inh 12

我认为您只想添加autovalidate: true,表单,以便在您关注更改验证时调用

 Form(
         key: _formKey,
         autovalidate: true,
         child:/*...*/
    )
Run Code Online (Sandbox Code Playgroud)

创建您的表单,例如

  var _formKey = GlobalKey<FormState>();
  bool _autoValidate = false;

  @override
  Widget build(BuildContext context) {
    return Form(
          key: _formKey,
          autovalidate: _autoValidate,
          child: /* ... */
        ),
      ),
    );
  }
Run Code Online (Sandbox Code Playgroud)

当你点击保存

void _onSignUpClicked(BuildContext context) {
    if (_formKey.currentState.validate()) {
      Scaffold.of(context).showSnackBar(SnackBar(content: Text("Successfully sign up")));
    } else {
      setState(() {
        _autoValidate = true;
      });
    }
  }
Run Code Online (Sandbox Code Playgroud)

  • 当字段内的文本更改时,自动验证会更新,并且会针对所有字段触发。看起来这个问题只想在单个字段上执行验证,并且仅在失去焦点时执行。 (6认同)

lad*_*kie 10

要在焦点从一个字段更改为下一个字段时验证文本字段,您需要FocusNode检测焦点何时被移除,并GlobalKey<FormFieldState>指示TextFormField其进行验证。这是一个示例:

class FormValidationDemo extends StatefulWidget {
  const FormValidationDemo({Key key}) : super(key: key);

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

class _FormValidationDemoState extends State<FormValidationDemo> {
  final _formKey = GlobalKey<FormState>();

  FocusNode focusNode1;
  FocusNode focusNode2;
  final field1Key = GlobalKey<FormFieldState>();
  final field2Key = GlobalKey<FormFieldState>();

  @override
  void initState() {
    super.initState();
    focusNode1 = FocusNode();
    focusNode2 = FocusNode();
    focusNode1.addListener(() {
      if (!focusNode1.hasFocus) {
        field1Key.currentState.validate();
      }
    });
    focusNode2.addListener(() {
      if (!focusNode2.hasFocus) {
        field2Key.currentState.validate();
      }
    });
  }

  @override
  void dispose() {
    focusNode1.dispose();
    focusNode2.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Form Demo')),
      body: Form(
        key: _formKey,
        child: Column(
          children: [
            TextFormField(
              key: field1Key,
              focusNode: focusNode1,
              validator: (value) {
                if (value.isEmpty) {
                  return 'Please enter a value.';
                }
                return null;
              },
            ),
            TextFormField(
              key: field2Key,
              focusNode: focusNode2,
              validator: (value) {
                if (value.isEmpty) {
                  return 'Please enter a value.';
                }
                return null;
              },
            ),
          ],
        ),
      ),
    );
  }
}




Run Code Online (Sandbox Code Playgroud)


aWe*_*per 8

将 autoValidateMode 添加到您的表单中

autovalidateMode:AutovalidateMode.onUserInteraction,

child: Form(
      key: _formKey,
      autovalidateMode: AutovalidateMode.onUserInteraction,
      child: Column()
)
Run Code Online (Sandbox Code Playgroud)

自动验证还有两种禁用模式(从不自动验证)和始终模式(在所有情况下,即使没有任何用户交互)。

在这里阅读更多内容


Ibr*_*han 5

投入TextEditingControllerTextField和使用addListener用于获取每一个变化。并在该侦听器内进行验证过程。


ike*_*fah 5

1.19
需要注意的是,在现在引入了AutovalidateMode具有三个基本常量的新参数之后,现在不推荐使用已接受的解决方案:

  1. always :用于自动验证 Form 和 FormField,即使没有用户交互。
  2. 禁用:不会发生自动验证。
  3. onUserInteraction :用于仅在每次用户交互后自动验证 Form 和 FormField。