我正在构建一个Flutter应用程序。我希望UI部分和逻辑部分保持分开,所以我将所有代码放在单独的类(不是小部件)中。
我的主窗口小部件文件
import "package:flutter/material.dart";
import 'package:google_sign_in/google_sign_in.dart';
import 'package:appname/Models/user.dart';
final GoogleSignIn googleSignIn = GoogleSignIn();
class googleLogin extends StatefulWidget {
@override
_googleLoginState createState() => _googleLoginState();
}
class _googleLoginState extends State<googleLogin> {
User user = new User();
@override
Widget build(BuildContext context) {
return Scaffold(
body:Container(
child:Column(
children: <Widget>[
MaterialButton(
padding: EdgeInsets.only(top:50),
onPressed: (){
setState(() {
user.signInWithGoogle();
});
},
child: Text("Log In")
),
MaterialButton(
padding: EdgeInsets.only(top:100),
onPressed: (){
setState(() {
user.signOutWithGoogle();
});
},
child: Text("Log Out")
),
if(user.username!="") Text(user.username),
if(user.email!="")Text(user.email),
if(user.imageurl!="") Image.network(user.imageurl),
],
)
)
);
}
}
我的用户模型类
import 'dart:convert';
import 'package:google_sign_in/google_sign_in.dart';
import 'package:appname/GoogleSignIn/GoogleSignIn.dart';
import 'package:http/http.dart' as http;
class User{
String _username="";
String _email="";
String _imageurl="";
String get imageurl=>_imageurl;
String get email => _email;
String get username => _username;
Future<void> signInWithGoogle() async {
final GoogleSignInAccount googleSignInAccount = await googleSignIn.signIn();
print(googleSignInAccount.displayName);
this._username = googleSignInAccount.displayName;
this._email = googleSignInAccount.email;
this._imageurl = googleSignInAccount.photoUrl;
createUser(googleSignInAccount.displayName, googleSignInAccount.email);
print('signInWithGoogle succeeded');
}
void signOutWithGoogle() async{
await googleSignIn.signOut();
this._username="";
this._email = "";
this._imageurl="";
print("User Sign Out");
}
Future<http.Response> createUser(String name, String email) async {
return http.post(
'http://172.20.10.3:8000/createuser/',
headers: <String, String>{
'Content-Type': 'application/json; charset=UTF-8',
},
body: jsonEncode(<String, String>{
'name':name,
'email':email
}),
);
}
}
我期望-单击“登录”按钮时,User
类中的变量值会更改。因此,我希望稍后在第一个代码文件中的Text
小部件显示用户的姓名和电子邮件。
会发生什么-当我单击“登录”按钮时,变量的值已更改,但是Text
字段未更改。
我在setState
上使用了onPressed()
,所以我只是希望状态会被更新。请帮忙。
注意-我已提及Flutter setState to another class?,Flutter: Calling SetState() from another class,Is it possible to change the state of another class using a button which is located at somewhere else in the widget tree 但它们不能解决我的问题。
答案 0 :(得分:0)
您没有等待任何异步功能,因此setState
将在更改不同变量的值之前完成。
使用await
关键字意味着您在继续执行之前等待方法执行结束。
您需要将代码更改为类似的内容
MaterialButton(
padding: EdgeInsets.only(top:50),
onPressed: () async {
await user.signInWithGoogle();
setState(() {});
},
child: Text("Log In")
),
MaterialButton(
padding: EdgeInsets.only(top:100),
onPressed: () async {
await user.signOutWithGoogle();
setState(() {});
},
child: Text("Log Out")
),
并更改signOutWithGoogle
以返回未来
Future signOutWithGoogle() async{
...
}