我在做什么
有两个页面:个人资料和登录页面。
首先显示个人资料页面,但当用户尚未登录时,个人资料页面不显示个人资料和显示登录按钮。
概要文件代码
bool loggedin = false; // If user already logged in return true
class Profile extends StatefulWidget {
const Profile({Key? key}) : super(key: key);
@override
_Profile createState() => _Profile();
}
class _Profile extends State<Profile> {
@override
Widget build(BuildContext context) {
return loggedin
? Column(children: [ //.... some user information
])
: needLogin(context);
}
}
Widget needLogin(BuildContext context) {
return Center(
TextButton(
onPressed: () {
Navigator.of(context).pushNamed("/login");
},
child: const Text(
"Login",
style: TextStyle(fontSize: 20),
)),
);
}
Loggin页面
// The code to login is omitted. if login succeeded do loggedin = true; in setState()
var user = FirebaseAuth.instance.currentUser;
if (user != null) {
Navigator.of(context).pop();
setState(() {
loggedin = true;
});
}
// Then back to profile page automatically
我在setState()
中做了loggedin = true;
,但个人资料页面仍然显示needLogin()
的登录按钮。
我在StatefulWidget
之外写needLogin()
的原因是为了与其他StatefulWidget
重用它。
在Navigator.of(context).pushNamed()
生成的页面中调用setState()
,如何更新上一页?
您必须编辑needLogin
方法,并通过Navigator返回成功状态/bool:
概要文件代码
class Profile extends StatefulWidget {
const Profile({Key? key}) : super(key: key);
@override
_Profile createState() => _Profile();
}
class _Profile extends State<Profile> {
@override
Widget build(BuildContext context) {
return loggedin
? Column(children: [ //.... some user information
])
: needLogin(context, () => setState(() {loggedIn = true}));
}
}
Widget needLogin(BuildContext context, void Function() setStateFunction) {
return Center(
child: TextButton(
onPressed: () async {
await Navigator.of(context)
.pushNamed("/login")
.then((result) {
if (result as bool) {
setStateFunction.call();
}
});
},
child: const Text(
"Login",
style: TextStyle(fontSize: 20),
)),
);
}
登录页面
var user = FirebaseAuth.instance.currentUser;
if (user != null) {
Navigator.pop(context, true);
}
不要
loggedin
在小部件外部。
使用于:
类_Profile扩展状态{
另外,您可能想要研究一些状态管理技术,例如带有Change notification的Provider。它非常容易使用,并且可以完全满足您的需求。
UI不应该包含业务逻辑,而应该基于某种类型的控制器来呈现。这使得代码更加一致,可读性和可测试性。