尝试验证 TextFormField 输入时出现异常

Exception while trying to validate a TextFormField Input

我正在尝试验证项目中的两个 TextFormFields(电子邮件和密码)。但是我在验证 TextFormField 时遇到异常。有人可以让我知道我哪里出错了吗?或者如何修复错误。

我得到的错误是:════════ Exception caught by gesture ═══════════════════════════════════════════ Null check operator used on a null value ════════════════════════════════════════════════════════════════════════════════

我的代码:

class _LoginState extends State<Login> {
  @override
  Widget build(BuildContext context) {
    final _formKey = GlobalKey<FormState>();

    TextEditingController emailController;
    TextEditingController passwordController;
    final authService = Provider.of<AuthService>(context);
    emailController = TextEditingController();
    passwordController = TextEditingController();
    return Scaffold(
      backgroundColor: Colors.white,
      body: SingleChildScrollView(
          child: Column(children: <Widget>[
        Padding(
          padding: const EdgeInsets.only(top: 60.0),
          child: Center(
            child: Container(
                width: 300,
                height: 380,
                decoration:
                    BoxDecoration(borderRadius: BorderRadius.circular(50.0)),
                child: Image.asset(
                  'assets/images/logo.png',
                )),
          ),
        ),
        const SizedBox(height: 15.0),
        Padding(
          padding: EdgeInsets.only(left: 25.0, right: 25.0, top: 0, bottom: 0),
          child: TextFormField(
            validator: (value) {
              if (value == null || value.isEmpty) {
                return 'Please enter the email.';
              }
              return null;
            },
            controller: emailController,
            decoration: InputDecoration(
                border: OutlineInputBorder(
                  borderRadius: BorderRadius.circular(60),
                ),
                prefixIcon: const Icon(Icons.mail),
                labelText: 'E-Mail',
                hintText: 'admin@gmail.com'),
          ),
        ),
        Padding(
          padding: EdgeInsets.only(left: 25.0, right: 25.0, top: 15, bottom: 0),
          child: TextFormField(
            validator: (value) {
              if (value == null || value.isEmpty) {
                return 'Please enter the password.';
              }
              return null;
            },
            controller: passwordController,
            obscureText: true,
            decoration: InputDecoration(
                border: OutlineInputBorder(
                  borderRadius: BorderRadius.circular(60),
                ),
                prefixIcon: const Icon(Icons.vpn_key),
                labelText: 'Password',
                hintText: 'Enter your Password'),
          ),
        ),
        const SizedBox(
          height: 100,
        ),
        TextButton(
            onPressed: () {
              if (_formKey.currentState!.validate()) {
                ScaffoldMessenger.of(context).showSnackBar(
                  const SnackBar(content: Text('Processing')),
                );
              }
              authService.signInWithEmailAndPassword(context,
                  emailController.text.trim(), passwordController.text.trim());
            },
            child: const Text(
              'Login',
              textAlign: TextAlign.center,
            )),
        MaterialButton(
            onPressed: () {
              Navigator.push(context,
                  MaterialPageRoute(builder: (context) => forgotPassword()));
            },
            child: Text(
              'Forgot Password',
              textAlign: TextAlign.center,
              style: TextStyle(fontSize: 13.0, color: Colors.red.shade900),
            ))
      ])),
    );
  }
}

提前致谢。

您导致此错误的原因是您在代码中定义了 _formkey 而不是 used,因此它没有任何 valueState 对现在您必须将 TextFormField 包装在 Form 小部件中并且需要传递定义的 key,您可以检查下面的代码

final _formKey = GlobalKey<FormState>();

class _LoginState extends State<Login> {
  @override
  Widget build(BuildContext context) {

    TextEditingController emailController;
    TextEditingController passwordController;
    final authService = Provider.of<AuthService>(context);
    emailController = TextEditingController();
    passwordController = TextEditingController();
    return Scaffold(
      backgroundColor: Colors.white,
      body: SingleChildScrollView(
          child: Column(children: <Widget>[
            Padding(
              padding: const EdgeInsets.only(top: 60.0),
              child: Center(
                child: Container(
                    width: 300,
                    height: 380,
                    decoration:
                    BoxDecoration(borderRadius: BorderRadius.circular(50.0)),
                    child: Image.asset(
                      'assets/images/logo.png',
                    )),
              ),
            ),
            const SizedBox(height: 15.0),
            Form(
              key: _formKey,
              child: Padding(
                padding: EdgeInsets.only(left: 25.0, right: 25.0, top: 0, bottom: 0),
                child: TextFormField(
                  validator: (value) {
                    if (value == null || value.isEmpty) {
                      return 'Please enter the email.';
                    }
                    return null;
                  },
                  controller: emailController,
                  decoration: InputDecoration(
                      border: OutlineInputBorder(
                        borderRadius: BorderRadius.circular(60),
                      ),
                      prefixIcon: const Icon(Icons.mail),
                      labelText: 'E-Mail',
                      hintText: 'admin@gmail.com'),
                ),
              ),
            ),
            Padding(
              padding: EdgeInsets.only(left: 25.0, right: 25.0, top: 15, bottom: 0),
              child: TextFormField(
                validator: (value) {
                  if (value == null || value.isEmpty) {
                    return 'Please enter the password.';
                  }
                  return null;
                },
                controller: passwordController,
                obscureText: true,
                decoration: InputDecoration(
                    border: OutlineInputBorder(
                      borderRadius: BorderRadius.circular(60),
                    ),
                    prefixIcon: const Icon(Icons.vpn_key),
                    labelText: 'Password',
                    hintText: 'Enter your Password'),
              ),
            ),
            const SizedBox(
              height: 100,
            ),
            TextButton(
                onPressed: () {
                  if (_formKey.currentState!.validate()) {
                    ScaffoldMessenger.of(context).showSnackBar(
                      const SnackBar(content: Text('Processing')),
                    );
                  }
                  authService.signInWithEmailAndPassword(context,
                      emailController.text.trim(), passwordController.text.trim());
                },
                child: const Text(
                  'Login',
                  textAlign: TextAlign.center,
                )),
            MaterialButton(
                onPressed: () {
                  Navigator.push(context,
                      MaterialPageRoute(builder: (context) => forgotPassword()));
                },
                child: Text(
                  'Forgot Password',
                  textAlign: TextAlign.center,
                  style: TextStyle(fontSize: 13.0, color: Colors.red.shade900),
                ))
          ])),
    );
  }
}

您的代码段中没有使用 Form 小部件 _formKey,这就是它从 _formKey.currentState!.validate() 中抛出错误的原因。因为您使用的 ! 表示 currentState of formKey 永远不会为空。

您可以先检查空状态来处理它。

 TextButton(
             onPressed: () {
               if (_formKey.currentState == null) {
                 return; // dont execute rest code
               }
               if (_formKey.currentState!.validate()) {
                 ScaffoldMessenger.of(context).showSnackBar(
                   const SnackBar(content: Text('Processing')),
                 );
               authService.signInWithEmailAndPassword(context, 
              emailController.text.trim(),
               passwordController.text.trim());
               },

Form 小部件放在 Column 小部件之前。

   body: SingleChildScrollView(
          child: Form(
        key: _formKey,
        child: Column(children: <Widget>[
          Padding(
            padding: const EdgeInsets.only(top: 60.0),
            child: Center(

更多关于forms validation