【问题标题】:TextFormField validator not working - The method 'validate' was called on nullTextFormField 验证器不起作用 - 在 null 上调用了方法“验证”
【发布时间】:2019-07-22 08:58:01
【问题描述】:

我正在尝试为新的颤振应用构建一个简单的登录页面。小部件树是非常基本的。它由一个包含 Scaffold 的 MaterialApp 组成。 Scaffold 的“家”是一个 StatefulWidget,其中包含带有两个 TextFormField 的 Form。

TextFormFields 有“验证器”代码来检查空值。

有一个按钮在按下时会调用方法“validateAndSave”。在这个方法中,我为 GlobalKey 的一个实例调用了“验证”方法。

单击按钮时,验证器似乎没有触发,我收到以下错误消息:

I/flutter (10459): ══╡ EXCEPTION CAUGHT BY GESTURE ╞═══════════════════════════════════════════════════════════════════
I/flutter (10459): The following NoSuchMethodError was thrown while handling a gesture:
I/flutter (10459): The method 'validate' was called on null.
I/flutter (10459): Receiver: null
I/flutter (10459): Tried calling: validate()
I/flutter (10459): 
I/flutter (10459): When the exception was thrown, this was the stack:
I/flutter (10459): #0      Object.noSuchMethod (dart:core/runtime/libobject_patch.dart:50:5)
I/flutter (10459): #1      _LoginForm.validateAndSave (package:playground/main.dart:33:13)

我尝试在项目上运行 flutter clean 并重新运行应用程序。我仍然收到错误消息。

这是我正在运行的代码。

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Playground',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: Scaffold(body:LoginForm()
      ),
    );
  }
}

class LoginForm extends StatefulWidget {
  @override
  State<StatefulWidget> createState() => _LoginForm();
}

class _LoginForm extends State<LoginForm>{
  // GlobalKey<FormState> formKey = new GlobalKey();
  final _formKey = new GlobalKey<FormState>();
  String _email;
  String _password;

  void validateAndSave(){
    final form = _formKey.currentState;
    if(form.validate())
    {
      print ('Form is valid');
    }
    else
    {
      print('form is invalid');
    }
  }

  @override
  Widget build(BuildContext context) {
    return Container(
        padding: EdgeInsets.only(left: 15.0, right: 15.0),
        child: Form(
            child: Column(
              // mainAxisAlignment: MainAxisAlignment.center,
                crossAxisAlignment: CrossAxisAlignment.stretch,
                children: <Widget>[
                  SizedBox(height: 150.0,),
                  //input field for email
                  TextFormField(
                    decoration: InputDecoration(labelText: 'Email'),
                    validator: (value) => value.isEmpty ? 'Email cannot be blank':null,
                    //       onSaved: (value) => _email = value,
                  ),
                  //input field for password
                  TextFormField(
                    decoration: InputDecoration(labelText: 'Password'),
                    obscureText: true,
                    validator: (value) => value.isEmpty ? 'Password cannot be blank':null,
                    //     onSaved: (value) => _password = value,
                  ),
                  RaisedButton(
                    child: Text ('Login', style: TextStyle(fontSize: 20.0),),
                    onPressed: validateAndSave,
                  )
                ]
            )
        )
    );
  }
}

我觉得我错过了代码中的某些内容。在解决这个问题时,我将不胜感激。

【问题讨论】:

    标签: flutter validation dart textfield


    【解决方案1】:

    您没有将key 添加到表单中,此代码应该可以工作:

    class _LoginForm extends State<LoginForm> {
      // GlobalKey<FormState> formKey = GlobalKey();
      final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
      String _email;
      String _password;
    
      void validateAndSave() {
        final FormState form = _formKey.currentState;
        if (form.validate()) {
          print('Form is valid');
        } else {
          print('Form is invalid');
        }
      }
    
      @override
      Widget build(BuildContext context) {
        return Container(
          padding: EdgeInsets.only(left: 15.0, right: 15.0),
          child: Form(
            key: _formKey,
            child: Column(
              // mainAxisAlignment: MainAxisAlignment.center,
              crossAxisAlignment: CrossAxisAlignment.stretch,
              children: <Widget>[
                SizedBox(
                  height: 150.0,
                ),
                // input field for email
                TextFormField(
                  decoration: InputDecoration(labelText: 'Email'),
                  validator: (value) =>
                      value.isEmpty ? 'Email cannot be blank' : null,
                  // onSaved: (value) => _email = value,
                ),
                // input field for password
                TextFormField(
                  decoration: InputDecoration(labelText: 'Password'),
                  obscureText: true,
                  validator: (value) =>
                      value.isEmpty ? 'Password cannot be blank' : null,
                  // onSaved: (value) => _password = value,
                ),
                RaisedButton(
                  child: Text(
                    'Login',
                    style: TextStyle(fontSize: 20.0),
                  ),
                  onPressed: validateAndSave,
                ),
              ],
            ),
          ),
        );
      }
    }
    

    【讨论】:

    • 这是一个很棒的示例,说明如何在单击提交后进行验证,因此在您输入电子邮件时它不会显示为红色。
    【解决方案2】:

    如果有人即使添加键也有同样的错误,你的结构是:

    Form => ListView => [TextFormField(s)], 
    

    尝试改变结构:

    Form => SingleScrollView => Column
    

    这个改变对我有用。

    编码愉快。

    【讨论】:

    • 非常感谢!这为今天节省了很多时间! :)
    • @Pedro Molina 你能解释一下为什么会这样吗?
    猜你喜欢
    • 2023-01-12
    • 2019-02-22
    • 2018-01-18
    • 2019-05-01
    • 2021-05-25
    • 2014-09-24
    • 2012-01-29
    • 1970-01-01
    • 2020-10-29
    相关资源
    最近更新 更多