Flutter [ERROR:flutter/lib/ui/ui_dart_state.cc(209)] Unhandled Exception: type 'Null' is not a subtype of type 'BuildContext'
Flutter [ERROR:flutter/lib/ui/ui_dart_state.cc(209)] Unhandled Exception: type 'Null' is not a subtype of type 'BuildContext'
我正在尝试验证用户输入的用于注册的输入数据并收到此错误 [错误:flutter/lib/ui/ui_dart_state.cc(209)] 未处理的异常:类型 'Null' 不是类型 'BuildContext'
的子类型
这是我的代码:
class _LoginState extends State<Login> {
final AuthService _auth = AuthService();
final _formKey = GlobalKey<FormState>();
TextEditingController _emailController = TextEditingController();
TextEditingController _passwordController = TextEditingController();
GoogleSignIn _googleSignIn = GoogleSignIn(scopes: ['email']);
late String _email, _password;
String error = "";
@override
void initState() {
super.initState();
}
bool _isObscure = true;
@override
Widget build(BuildContext context) {
MediaQueryData mediaQueryData = MediaQuery.of(context);
GoogleSignInAccount? user = _googleSignIn.currentUser;
final isKeyboard = MediaQuery.of(context).viewInsets.bottom != 0;
return Scaffold(
resizeToAvoidBottomInset: false,
appBar: !isKeyboard
? AppBar(
titleSpacing: 12,
leading: ModalRoute.of(context)?.canPop == true
? IconButton(
splashColor: Colors.transparent,
padding: const EdgeInsets.only(left: 30.0, bottom: 15.0),
icon: Icon(
Icons.arrow_back,
size: 35,
),
onPressed: () => Navigator.of(context).pop(),
color: Colors.black,
)
: null,
title: Image.asset('images/logo-name.png'),
backgroundColor: new Color(0xffff),
shadowColor: Colors.transparent,
elevation: 0,
toolbarHeight: 90.0,
)
: null,
body: Center(
child: Column(
children: <Widget>[
if (!isKeyboard)
Container(
child: RichText(
textAlign: TextAlign.center,
text: TextSpan(
text: "Made e-Groceries easier",
style: TextStyle(
fontSize: mediaQueryData.textScaleFactor /
mediaQueryData.textScaleFactor *
33,
fontFamily: 'Inter',
fontWeight: FontWeight.w600,
color: Colors.black)),
),
width: mediaQueryData.size.width * 0.8,
),
Container(
child: Image(
image: AssetImage("images/login.png"), fit: BoxFit.contain),
),
Container(
width: mediaQueryData.size.width * 0.85,
child: Form(
key: _formKey,
child: SingleChildScrollView(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
TextFormField(
controller: _emailController,
validator: (input) {
if (input!.isEmpty)
return 'Pleas enter a valid Email';
},
decoration: InputDecoration(
focusedErrorBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.red),
),
errorBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.red),
),
errorStyle: TextStyle(height: 0.4),
contentPadding:
const EdgeInsets.symmetric(vertical: 20.0),
enabledBorder: OutlineInputBorder(
borderSide:
BorderSide(color: Color(0xff2C6846))),
focusColor: Color(0xff2C6846),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(
color: Color(0xff2C6846),
)),
labelStyle: TextStyle(color: Color(0xff2C6846)),
labelText: "Email",
prefixIcon:
Icon(Icons.mail, color: Color(0xff2C6846)),
),
onSaved: (input) => _email = input!),
SizedBox(height: 20),
TextFormField(
obscureText: _isObscure,
enableSuggestions: false,
autocorrect: false,
controller: _passwordController,
validator: (input) {
if (input!.length < 6)
return 'Provide minimum 6 character';
},
decoration: InputDecoration(
focusedErrorBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.red),
),
errorBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.red),
),
errorStyle: TextStyle(height: 0.4),
contentPadding: const EdgeInsets.symmetric(
vertical: 20.0),
enabledBorder: OutlineInputBorder(
borderSide:
BorderSide(color: Color(0xff2C6846))),
focusColor: Color(0xff2C6846),
focusedBorder: OutlineInputBorder(
borderSide:
BorderSide(color: Color(0xff2C6846))),
labelStyle:
TextStyle(color: Color(0xff2C6846)),
labelText: "Password",
suffixIcon: IconButton(
icon: Icon(
_isObscure
? Icons.visibility
: Icons.visibility_off,
color: Color(0xff2C6846),
),
onPressed: () {
setState(() {
_isObscure = !_isObscure;
});
},
),
prefixIcon: Icon(Icons.lock,
color: Color(0xff2C6846))),
onSaved: (input) => _password = input!),
])))),
SizedBox(height: 20),
ButtonTheme(
buttonColor: Color(0xff2C6846),
minWidth: mediaQueryData.size.width * 0.85,
height: 60.0,
child: RaisedButton(
shape: RoundedRectangleBorder(
borderRadius: new BorderRadius.circular(5.0),
),
padding: EdgeInsets.fromLTRB(70, 10, 70, 10),
onPressed: () {
if (_formKey.currentState!.validate()) {
signInUser();
}
},
child: Text('Log In',
style: TextStyle(
color: Colors.white,
fontSize: 20.0,
fontWeight: FontWeight.w600))),
)
],
),
),
);
}
void signInUser() async {
dynamic authResult = await _auth.loginUser(
_emailController.text, _passwordController.text);
if (authResult == null) {
print("Sign in error. Could not be able to login");
} else {
_emailController.clear();
_passwordController.clear();
print('Sign in Successful');
Navigator.push(
context, MaterialPageRoute(builder: (context) => HomePage()));
}
}
}
以上代码适用于AuthService.dart:
class AuthService {
final FirebaseAuth _auth = FirebaseAuth.instance;
showError(Object errormessage) {
var context;
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: Text('Note'),
content: Text(errormessage.toString()),
actions: <Widget>[
FlatButton(
onPressed: () {
Navigator.of(context).pop();
},
child: Text('OK'))
],
);
});
}
Future loginUser(String email, String password) async {
try {
UserCredential result = await _auth.signInWithEmailAndPassword(
email: email.toString(), password: password.toString());
return result.user;
} catch (e) {
showError(e);
}
}
}
忽略乱七八糟的缩进,因为这是我第一次使用堆栈溢出。
问题可能来自
Navigator.push(
context, MaterialPageRoute(builder: (context) => HomePage()));
因此创建全局 BuildContext 变量并从构建方法初始化它。或者将上下文作为参数发送。喜欢
signInUser(BuildContext context)
...
showError(Object errormessage) {
var context;
showDialog(
context: context,
...
showDialog 方法采用上下文参数,它使用此上下文查找有关您的应用程序的一些特别有用的信息,以便正确显示对话框,您没有传递正确的上下文。
你所做的是先声明一个变量context
然后传递它,变量的值默认为null,所以你得到一个错误。
要解决此问题,您需要传递您的应用使用的真实上下文:
...
showError(BuildContext context, Object errormessage) {
showDialog(
context: context,
...
然后:
Future loginUser(BuildContext context, String email, String password) async {
try {
UserCredential result = await _auth.signInWithEmailAndPassword(
email: email.toString(), password: password.toString());
return result.user;
} catch (e) {
showError(context, e);
}
}
最后:
...
void signInUser() async {
dynamic authResult = await _auth.loginUser(context, _emailController.text, _passwordController.text);
...
'Null' is not a subtype of type 'BuildContext' 错误意味着代码需要你的 BuildContext 但可能你给了 null。所以你应该使用 parts 检查 BuildContext。
当我查看您的代码时,我看到了错误行。
错误是您定义了上下文而不设置任何内容。所以它的值为空。
您应该传递带有参数的上下文。如果您传递上下文,您的问题将得到解决。
showError(Object errormessage) {
var context;
showDialog(
context: context,
我正在尝试验证用户输入的用于注册的输入数据并收到此错误 [错误:flutter/lib/ui/ui_dart_state.cc(209)] 未处理的异常:类型 'Null' 不是类型 'BuildContext'
的子类型这是我的代码:
class _LoginState extends State<Login> {
final AuthService _auth = AuthService();
final _formKey = GlobalKey<FormState>();
TextEditingController _emailController = TextEditingController();
TextEditingController _passwordController = TextEditingController();
GoogleSignIn _googleSignIn = GoogleSignIn(scopes: ['email']);
late String _email, _password;
String error = "";
@override
void initState() {
super.initState();
}
bool _isObscure = true;
@override
Widget build(BuildContext context) {
MediaQueryData mediaQueryData = MediaQuery.of(context);
GoogleSignInAccount? user = _googleSignIn.currentUser;
final isKeyboard = MediaQuery.of(context).viewInsets.bottom != 0;
return Scaffold(
resizeToAvoidBottomInset: false,
appBar: !isKeyboard
? AppBar(
titleSpacing: 12,
leading: ModalRoute.of(context)?.canPop == true
? IconButton(
splashColor: Colors.transparent,
padding: const EdgeInsets.only(left: 30.0, bottom: 15.0),
icon: Icon(
Icons.arrow_back,
size: 35,
),
onPressed: () => Navigator.of(context).pop(),
color: Colors.black,
)
: null,
title: Image.asset('images/logo-name.png'),
backgroundColor: new Color(0xffff),
shadowColor: Colors.transparent,
elevation: 0,
toolbarHeight: 90.0,
)
: null,
body: Center(
child: Column(
children: <Widget>[
if (!isKeyboard)
Container(
child: RichText(
textAlign: TextAlign.center,
text: TextSpan(
text: "Made e-Groceries easier",
style: TextStyle(
fontSize: mediaQueryData.textScaleFactor /
mediaQueryData.textScaleFactor *
33,
fontFamily: 'Inter',
fontWeight: FontWeight.w600,
color: Colors.black)),
),
width: mediaQueryData.size.width * 0.8,
),
Container(
child: Image(
image: AssetImage("images/login.png"), fit: BoxFit.contain),
),
Container(
width: mediaQueryData.size.width * 0.85,
child: Form(
key: _formKey,
child: SingleChildScrollView(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
TextFormField(
controller: _emailController,
validator: (input) {
if (input!.isEmpty)
return 'Pleas enter a valid Email';
},
decoration: InputDecoration(
focusedErrorBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.red),
),
errorBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.red),
),
errorStyle: TextStyle(height: 0.4),
contentPadding:
const EdgeInsets.symmetric(vertical: 20.0),
enabledBorder: OutlineInputBorder(
borderSide:
BorderSide(color: Color(0xff2C6846))),
focusColor: Color(0xff2C6846),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(
color: Color(0xff2C6846),
)),
labelStyle: TextStyle(color: Color(0xff2C6846)),
labelText: "Email",
prefixIcon:
Icon(Icons.mail, color: Color(0xff2C6846)),
),
onSaved: (input) => _email = input!),
SizedBox(height: 20),
TextFormField(
obscureText: _isObscure,
enableSuggestions: false,
autocorrect: false,
controller: _passwordController,
validator: (input) {
if (input!.length < 6)
return 'Provide minimum 6 character';
},
decoration: InputDecoration(
focusedErrorBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.red),
),
errorBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.red),
),
errorStyle: TextStyle(height: 0.4),
contentPadding: const EdgeInsets.symmetric(
vertical: 20.0),
enabledBorder: OutlineInputBorder(
borderSide:
BorderSide(color: Color(0xff2C6846))),
focusColor: Color(0xff2C6846),
focusedBorder: OutlineInputBorder(
borderSide:
BorderSide(color: Color(0xff2C6846))),
labelStyle:
TextStyle(color: Color(0xff2C6846)),
labelText: "Password",
suffixIcon: IconButton(
icon: Icon(
_isObscure
? Icons.visibility
: Icons.visibility_off,
color: Color(0xff2C6846),
),
onPressed: () {
setState(() {
_isObscure = !_isObscure;
});
},
),
prefixIcon: Icon(Icons.lock,
color: Color(0xff2C6846))),
onSaved: (input) => _password = input!),
])))),
SizedBox(height: 20),
ButtonTheme(
buttonColor: Color(0xff2C6846),
minWidth: mediaQueryData.size.width * 0.85,
height: 60.0,
child: RaisedButton(
shape: RoundedRectangleBorder(
borderRadius: new BorderRadius.circular(5.0),
),
padding: EdgeInsets.fromLTRB(70, 10, 70, 10),
onPressed: () {
if (_formKey.currentState!.validate()) {
signInUser();
}
},
child: Text('Log In',
style: TextStyle(
color: Colors.white,
fontSize: 20.0,
fontWeight: FontWeight.w600))),
)
],
),
),
);
}
void signInUser() async {
dynamic authResult = await _auth.loginUser(
_emailController.text, _passwordController.text);
if (authResult == null) {
print("Sign in error. Could not be able to login");
} else {
_emailController.clear();
_passwordController.clear();
print('Sign in Successful');
Navigator.push(
context, MaterialPageRoute(builder: (context) => HomePage()));
}
}
}
以上代码适用于AuthService.dart:
class AuthService {
final FirebaseAuth _auth = FirebaseAuth.instance;
showError(Object errormessage) {
var context;
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: Text('Note'),
content: Text(errormessage.toString()),
actions: <Widget>[
FlatButton(
onPressed: () {
Navigator.of(context).pop();
},
child: Text('OK'))
],
);
});
}
Future loginUser(String email, String password) async {
try {
UserCredential result = await _auth.signInWithEmailAndPassword(
email: email.toString(), password: password.toString());
return result.user;
} catch (e) {
showError(e);
}
}
}
忽略乱七八糟的缩进,因为这是我第一次使用堆栈溢出。
问题可能来自
Navigator.push(
context, MaterialPageRoute(builder: (context) => HomePage()));
因此创建全局 BuildContext 变量并从构建方法初始化它。或者将上下文作为参数发送。喜欢
signInUser(BuildContext context)
...
showError(Object errormessage) {
var context;
showDialog(
context: context,
...
showDialog 方法采用上下文参数,它使用此上下文查找有关您的应用程序的一些特别有用的信息,以便正确显示对话框,您没有传递正确的上下文。
你所做的是先声明一个变量context
然后传递它,变量的值默认为null,所以你得到一个错误。
要解决此问题,您需要传递您的应用使用的真实上下文:
...
showError(BuildContext context, Object errormessage) {
showDialog(
context: context,
...
然后:
Future loginUser(BuildContext context, String email, String password) async {
try {
UserCredential result = await _auth.signInWithEmailAndPassword(
email: email.toString(), password: password.toString());
return result.user;
} catch (e) {
showError(context, e);
}
}
最后:
...
void signInUser() async {
dynamic authResult = await _auth.loginUser(context, _emailController.text, _passwordController.text);
...
'Null' is not a subtype of type 'BuildContext' 错误意味着代码需要你的 BuildContext 但可能你给了 null。所以你应该使用 parts 检查 BuildContext。 当我查看您的代码时,我看到了错误行。 错误是您定义了上下文而不设置任何内容。所以它的值为空。 您应该传递带有参数的上下文。如果您传递上下文,您的问题将得到解决。
showError(Object errormessage) {
var context;
showDialog(
context: context,