我正在开发一个带有flutter的登录表单。当用户单击submit
按钮时,它将连接Firebase Auth以查看凭据并登录用户。在此过程之前,我需要向用户显示一个CircularProgressBar
。为了查看登录过程是否完成,我使用FutureBuilder
。下面是我的代码
final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
class LoginPage extends StatelessWidget {
LoginPage() {}
@override
Widget build(BuildContext context) {
return Scaffold(
key: _scaffoldKey,
body: Container(
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: [
Color.fromRGBO(11, 51, 83, 90),
Color.fromRGBO(4, 18, 30, 1)
])),
child: LoginForm()),
);
}
}
class LoginForm extends StatefulWidget {
@override
State<StatefulWidget> createState() {
// TODO: implement createState
return LoginFormState();
}
}
class LoginFormState extends State<LoginForm> {
final _formKey = GlobalKey<FormState>();
final FirebaseAuth _auth = FirebaseAuth.instance;
TextEditingController emailController = TextEditingController();
TextEditingController passwordController = TextEditingController();
@override
Widget build(BuildContext context) {
// TODO: implement build
return ListView(
children: <Widget>[
Container(
child: _buildLogo(),
margin:
EdgeInsets.only(top: MediaQuery.of(context).size.height * 0.20),
),
Container(
child: _buildForm(),
margin: EdgeInsets.only(left: 10, right: 10, top: 83),
)
],
);
}
Widget _buildLogo() {
return Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Image.asset(
"assets/images/logo.png",
fit: BoxFit.fill,
)
],
);
}
Widget _buildForm() {
return Form(
key: _formKey,
child: Column(
children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Flexible(
flex: 1,
child: Container(
child: Icon(
Icons.person,
color: Colors.white,
),
// child: ImageIcon(
// AssetImage("assets/images/email_24px.png"),
// color: Colors.white,
// ),
margin: EdgeInsets.only(right: 5, bottom: 10)),
),
Flexible(
flex: 7,
child: SizedBox(
height: 60,
child: TextFormField(
controller: emailController,
validator: (value) {
if (value.isEmpty) {
return 'Please enter some text';
}
return null;
},
decoration: InputDecoration(
filled: true,
fillColor: Colors.white,
contentPadding:
const EdgeInsets.only(top: 2, bottom: 2, left: 8),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(30.0),
),
hintText: "Email",
),
),
))
],
),
Container(
margin: EdgeInsets.only(top: 25),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Flexible(
flex: 1,
child: Container(
child: Icon(Icons.lock, color: Colors.white),
margin: EdgeInsets.only(right: 5, bottom: 10),
),
),
Flexible(
flex: 7,
child: SizedBox(
height: 60,
child: TextFormField(
controller: passwordController,
validator: (value) {
if (value.isEmpty) {
return 'Please enter some text';
}
return null;
},
decoration: InputDecoration(
filled: true,
fillColor: Colors.white,
contentPadding:
const EdgeInsets.only(top: 2, bottom: 2, left: 8),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(30.0),
),
hintText: "Password",
),
),
))
],
),
),
Container(
child: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
FlatButton(
materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
child: Text(
"Forgot Password?",
style: Theme.of(context).textTheme.body1,
),
onPressed: () {},
),
],
),
),
Container(
margin: EdgeInsets.only(top: 40, left: 25, right: 10, bottom: 20),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Flexible(
child: SizedBox(
width: double.infinity,
height: 40,
child: RaisedButton(
color: Color.fromRGBO(0, 72, 128, 100),
textColor: Colors.white,
shape: RoundedRectangleBorder(
borderRadius: new BorderRadius.circular(18.0),
side:
BorderSide(color: Color.fromRGBO(0, 72, 128, 100))),
child: Text(
"LOGIN",
style: Theme.of(context).textTheme.button,
),
onPressed: () {
if (_formKey.currentState.validate()) {
FutureBuilder(
future:
Provider.of<AuthService>(context, listen: false)
.signInWithEmail(emailController.text,
passwordController.text),
builder:
(BuildContext context, AsyncSnapshot snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
Navigator.pushNamed(context, "/home");
} else {
_scaffoldKey.currentState.showSnackBar(SnackBar(
duration: Duration(seconds: 4),
content: Row(
children: <Widget>[
new CircularProgressIndicator(),
new Text(" Signing-In...")
],
),
));
}
},
);
// signInWithEmail("test@test.com","test123");
}
},
),
))
],
),
)
],
),
);
}
Future<String> signInWithEmail(String email, String password) async {
FirebaseUser user;
try {
AuthResult result = await _auth.signInWithEmailAndPassword(
email: email, password: password);
user = result.user;
if (user != null) {
print("SIgn in success: " + user.email);
} else {
print("sign in failed");
}
} catch (e) {
print(e.toString());
}
}
@override
void initState() {
// TODO: implement initState
super.initState();
}
@override
void dispose() {
emailController.dispose();
passwordController.dispose();
super.dispose();
}
}
hERE当按下按钮时,我可以看到用户已登录,但我看不到CircularProgress
,或者我没有指向home
页面。
为什么会这样?
尝试以下操作:
FutureBuilder(
future:
Provider.of<AuthService>(context, listen: false)
.signInWithEmail(emailController.text,
passwordController.text),
builder:
(BuildContext context, AsyncSnapshot snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
Navigator.pushNamed(context, "/home");
} else {
_scaffoldKey.currentState.showSnackBar(SnackBar(
duration: Duration(seconds: 4),
content: Row(
children: <Widget>[
new CircularProgressIndicator(),
new Text(" Signing-In...")
],
),
));
}
return new CircularProgressIndicator();
},
);
在if-else添加return new CircularProgressIndicator
之外,这应该在开始时显示圆形指示符,然后当future
完成时,它将进入if