TextFormField 验证器不工作 - 方法 'validate' 被调用为 null
TextFormField validator not working - The method 'validate' was called on null
我正在尝试为新的 Flutter 应用构建一个简单的登录页面。小部件树是非常基本的。它由一个包含脚手架的 MaterialApp 组成。 Scaffold 的 'home' 是一个 StatefulWidget,里面包含了 Form,里面有两个 TextFormField。
TextFormFields 有 'validator' 代码来检查空值。
有一个按钮在按下时调用方法 'validateAndSave'。在此方法中,我正在为 GlobalKey 的实例调用 'validate' 方法。
单击按钮时,验证器似乎没有触发,我收到以下错误消息:
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,
)
]
)
)
);
}
}
我觉得我在代码中遗漏了一些东西。如果能帮我解决这个问题,我将不胜感激。
您没有将 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,
),
],
),
),
);
}
}
如果有人在添加密钥时出现同样的错误,您的结构是:
Form => ListView => [TextFormField(s)],
尝试改变结构:
Form => SingleScrollView => Column
这个改变对我有用。
编码愉快。
问题已经解决了,但如果在添加密钥并将结构更改为以下之一后仍然无法正常工作:
Form => SingleChildScrollView => Column => [TextFormField(s)],
或
SingleChildScrollView => Form => Column => [TextFormField(s)],
尝试添加:
autovalidateMode: AutovalidateMode.onUserInteraction
例如:
TextFormField(
decoration: const InputDecoration(
icon: Icon(Icons.person),
labelText: 'User:',
),
onSaved: (){},
autovalidateMode:
AutovalidateMode.onUserInteraction,
validator: (value) {
if (value == null || value.isEmpty) {
return 'Please enter your user name.';
} else if (value.contains('@')) {
return 'Please don\'t use the @ char.';
}
return null;
},
textInputAction: TextInputAction.next,
),
我正在尝试为新的 Flutter 应用构建一个简单的登录页面。小部件树是非常基本的。它由一个包含脚手架的 MaterialApp 组成。 Scaffold 的 'home' 是一个 StatefulWidget,里面包含了 Form,里面有两个 TextFormField。
TextFormFields 有 'validator' 代码来检查空值。
有一个按钮在按下时调用方法 'validateAndSave'。在此方法中,我正在为 GlobalKey 的实例调用 'validate' 方法。
单击按钮时,验证器似乎没有触发,我收到以下错误消息:
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,
)
]
)
)
);
}
}
我觉得我在代码中遗漏了一些东西。如果能帮我解决这个问题,我将不胜感激。
您没有将 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,
),
],
),
),
);
}
}
如果有人在添加密钥时出现同样的错误,您的结构是:
Form => ListView => [TextFormField(s)],
尝试改变结构:
Form => SingleScrollView => Column
这个改变对我有用。
编码愉快。
问题已经解决了,但如果在添加密钥并将结构更改为以下之一后仍然无法正常工作:
Form => SingleChildScrollView => Column => [TextFormField(s)],
或
SingleChildScrollView => Form => Column => [TextFormField(s)],
尝试添加:
autovalidateMode: AutovalidateMode.onUserInteraction
例如:
TextFormField(
decoration: const InputDecoration(
icon: Icon(Icons.person),
labelText: 'User:',
),
onSaved: (){},
autovalidateMode:
AutovalidateMode.onUserInteraction,
validator: (value) {
if (value == null || value.isEmpty) {
return 'Please enter your user name.';
} else if (value.contains('@')) {
return 'Please don\'t use the @ char.';
}
return null;
},
textInputAction: TextInputAction.next,
),