我正在我的项目的登录部分,我有一个包含电子邮件和密码的表单以及一个登录按钮,并且一切正常,它正在连接到Firebase。它向我发送结果是成功还是错误。我想问的是,我想在小吃店里显示错误,我已经整天都在尝试,但是没有用。谁能帮忙!错误消息如下:
FlutterError(查找已停用的小部件的祖先是不安全的。 此时,小部件的元素树的状态不再稳定。 为了在其dispose()方法中安全地引用窗口小部件的祖先,请通过在窗口小部件的didChangeDependencies()方法中调用InheritFromWidgetOfExactType()来保存对祖先的引用。
这是代码
import 'package:flutter/material.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:inclass/screens/authentication/signup.dart';
import 'package:inclass/screens/home/dashboard.dart';
import 'package:inclass/services/auth.dart';
import 'package:inclass/shared/loading.dart';
import 'package:inclass/widgets/logo.dart';
class Signin extends StatefulWidget {
@override
_SigninState createState() => _SigninState();
}
class _SigninState extends State<Signin> {
bool _obscureText = true;
final AuthService _auth = AuthService();
final _formkey = GlobalKey<FormState>();
bool loading = false;
final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
String email = '';
String password = '';
String error = '';
@override
Widget build(BuildContext context) {
return loading
? Loading()
: Scaffold(
key: _scaffoldKey,
backgroundColor: Colors.white,
body: Builder(
builder: (context) => ListView(children: <Widget>[
Form(
key: _formkey,
child: Column(
children: <Widget>[
Logo(),
SizedBox(
height: 20.0,
),
Stack(children: <Widget>[
Image(
height: 200.0,
width: MediaQuery.of(context).size.width,
image: AssetImage("assets/images/move.png"),
fit: BoxFit.cover,
),
Positioned(
bottom: 20.0,
right: 60.0,
child: Text(
'Sign In',
style: TextStyle(
color: Color(0xff7E8E9D),
fontSize: 22.0,
fontFamily: 'Poppins'),
textAlign: TextAlign.center,
)),
Positioned(
bottom: 5.0,
right: 80.0,
child: Text(
"As",
style: TextStyle(
color: Color(0xff7E8E9D),
fontSize: 15.0,
fontFamily: 'Poppins'),
textAlign: TextAlign.center,
),
)
]),
Padding(
padding: const EdgeInsets.only(
top: 20.0, left: 15.0, right: 15.0),
child: Center(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Container(
width: MediaQuery.of(context).size.width / 3,
height: 80.0,
decoration: new BoxDecoration(
//border: new Border.all(width: 1.0, color: Colors.black),
//shape: BoxShape.circle,
color: Colors.white,
boxShadow: <BoxShadow>[
// BoxShadow(
// color: Colors.grey,
// offset: Offset(1.0, 15.0),
// blurRadius: 64.0,
// ),
],
),
// color: Colors.blue,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Icon(
FontAwesomeIcons.graduationCap,
color: Color(0xffB57E20),
size: 22.0,
),
Padding(
padding:
const EdgeInsets.only(left: 15.0),
child: Text(
"Student",
style: TextStyle(
color: Color(0xffB57E20),
fontSize: 17.0,
fontFamily: 'Poppins'),
),
)
],
),
),
Container(
width: 1.0,
height: 60.0,
decoration: BoxDecoration(
border: Border(
right: BorderSide(color: Colors.black54),
),
),
),
Container(
width: MediaQuery.of(context).size.width / 3,
height: 80.0,
decoration: new BoxDecoration(
//border: new Border.all(width: 1.0, color: Colors.black),
//shape: BoxShape.circle,
color: Colors.white,
boxShadow: <BoxShadow>[
// BoxShadow(
// color: Colors.grey,
// offset: Offset(1.0, 15.0),
// blurRadius: 64.0,
// ),
],
),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Icon(
FontAwesomeIcons.chalkboardTeacher,
color: Color(0xff00315C),
size: 22.0,
),
Padding(
padding:
const EdgeInsets.only(left: 15.0),
child: Text(
"Teacher",
style: TextStyle(
color: Color(0xff00315C),
fontSize: 17.0,
fontFamily: 'Poppins'),
),
)
],
),
)
],
),
),
),
Container(
child: Padding(
padding: const EdgeInsets.only(
left: 20.0, right: 20.0, top: 40.0),
child: TextFormField(
onChanged: (val) {
setState(() => email = val);
},
validator: (val) =>
val.isEmpty ? "Email can't be Empty" : null,
// textAlign: TextAlign.center,
keyboardType: TextInputType.emailAddress,
// autofocus: true,
decoration: InputDecoration(
labelText: "Email",
contentPadding:
EdgeInsets.fromLTRB(20.0, 15.0, 20.0, 15.0),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(12.0),
borderSide:
BorderSide(color: Color(0xff00315C))),
suffixIcon: Icon(Icons.mail)),
),
),
),
Padding(
padding: const EdgeInsets.only(
top: 15.0, left: 20.0, right: 20.0, bottom: 20.0),
child: TextFormField(
obscureText: _obscureText,
onChanged: (val) {
setState(() => password = val);
},
validator: (val) => val.length < 6
? "Password Must be 6+ Char"
: null,
// textAlign: TextAlign.center,
// autofocus: true,
decoration: InputDecoration(
labelText: "Password",
contentPadding:
EdgeInsets.fromLTRB(20.0, 15.0, 20.0, 15.0),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(12.0),
borderSide:
BorderSide(color: Color(0xff00315C))),
suffixIcon: GestureDetector(
onTap: () {
setState(() {
_obscureText = !_obscureText;
});
},
child: Icon(
_obscureText
? Icons.visibility
: Icons.visibility_off,
semanticLabel: _obscureText
? 'show password'
: 'hide password',
),
)),
),
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Padding(
padding: const EdgeInsets.only(left: 20.0),
child: FlatButton(
child: Text("Forgot Password?",
style: TextStyle(color: Colors.grey)),
onPressed: () {},
),
),
Padding(
padding: const EdgeInsets.only(right: 25.0),
child: OutlineButton(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10),
),
highlightedBorderColor: Color(0xffB57E20),
borderSide: BorderSide(color: Color(0xffB57E20)),
onPressed: () async {
if (_formkey.currentState.validate()) {
setState(() => loading = true);
dynamic result =
await _auth.signInWithEmailAndPassword(
email, password);
if (result == null) {
setState(() {
error = 'Could not sign in';
loading = false;
});
_showToast(context,error);
print(error);
} else {
// Navigator.push(
// context,
// MaterialPageRoute(
// builder: (_) => DashBoard()));
print("Succeed");
}
}
},
padding: EdgeInsets.only(
left: 30.0,
right: 15.0,
top: 12.0,
bottom: 12.0),
color: Colors.white,
child: Row(
mainAxisAlignment:
MainAxisAlignment.spaceEvenly,
children: <Widget>[
Text(
"Next",
style: TextStyle(
color: Color(0xffB57E20),
fontSize: 17.0,
fontFamily: 'Poppins'),
),
Padding(
padding: const EdgeInsets.only(
left: 10.0, top: 2.0),
child: Icon(Icons.navigate_next,
color: Color(0xffB57E20), size: 30.0),
)
],
),
),
)
],
),
Padding(
padding: const EdgeInsets.all(28.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text("Not Registered Yet?",
style: TextStyle(
color: Colors.grey,
fontSize: 15.0,
fontFamily: 'Poppins')),
SizedBox(
width: 10.0,
),
GestureDetector(
onTap: () => Navigator.push(context,
MaterialPageRoute(builder: (_) => SignUp())),
child: Text("Sign Up",
style: TextStyle(
color: Color(0xff00315C),
fontSize: 15.0,
fontFamily: 'Poppins')),
),
],
),
)
],
),
),
]),
),
);
}
void _showToast(BuildContext context,String error) {
final scaffold = Scaffold.of(context);
scaffold.showSnackBar(SnackBar(
content: Text(error),
duration: Duration(seconds: 2),
action: SnackBarAction(
onPressed: () {
scaffold.hideCurrentSnackBar();
},
label: 'Okay',
),
));
}
}
我的代码有点混乱,我还没有重构
答案 0 :(得分:0)
它与您的代码的这一部分有关 返回
loading
? Loading()
: Scaffold(
当您点击“下一步”按钮时,您将这样的代码加载
setState(() => loading = true);
,它将从Widget树中删除脚手架。当您尝试使用_showToast函数时,尽管您再次调用setState loading = false,但Scaffold尚未准备就绪,无法移动到Widget树中,因此Scaffold.of无法获得所需的正确结果。
因此,如果您想显示加载屏幕,请提供Dialog或IndexedStack。
希望这可以解决您的问题。