我正在尝试验证项目中的两个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
的Form
小部件,这就是它从_formKey.currentState!.validate()
抛出错误的原因。因为您使用的!
表示currentState of formKey
永远不会为null。
您可以通过先检查null状态来处理它。
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(
有关表单验证的更多信息
您之所以导致此错误,是因为您在代码中定义了_formkey
,但没有定义used
,因此它现在没有任何value
或State
。您必须将TextFormField包装在Form小部件中,并需要传递定义的键,您可以在下面检查代码
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),
))
])),
);
}
}