问题描述
我正在尝试使用提供者创建一个简单的身份验证流程。我有三页:
- LoginPage
- OnboardingPage
- 主页
此应用的流程为:
- 如果用户是第一次打开该应用程序,则他/她将被重定向到入门菜单,然后登录到首页。
- 对于第二次用户,该应用程序首先检查登录状态,并重定向到->主页或直接转到主页。
这是我在代码中的设置:
main.dart
void main() {
runApp(MultiProvider(providers: [
ChangeNotifierProvider<StorageHelper>(create: (_) => StorageHelper()),ChangeNotifierProvider<AuthProvider>(create: (_) => AuthProvider()),],child: MyApp()));
}
class MyApp extends StatelessWidget {
Widget build(BuildContext context) {
return Consumer<AuthProvider>(builder: (final BuildContext context,final AuthProvider authProvider,final Widget child) {
print(authProvider.isAuthenticated); // this is false whenever I //click the logout from category(or other pushed pages) but the below ternary //operation is not executing
return MaterialApp(
title: 'My Poor App',debugShowCheckedModeBanner: false,theme: ThemeData(
primaryColor: Color(0xff29c17e),visualDensity: VisualDensity.adaptivePlatformDensity,),home: authProvider.isAuthenticated ? HomeScreen() : LoginScreen(),onGenerateRoute: Router.onGenerateRoute,);
});
}
}
LoginScreen.dart
class LoginScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
final authProvider = Provider.of<AuthProvider>(context,listen: false);
return Scaffold(
body: Center(
child: MaterialButton(
onPressed: () async {
await authProvider.emailLogin('user@email.com','pass');
},child: Text('Login'))),);
}
}
HomeScreen.dart
class HomeScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
final auth = Provider.of<AuthProvider>(context,listen: false);
return Scaffold(
body: Center(
child: MaterialButton(
elevation: 2,onPressed: () {
Navigator.push(
context,MaterialPageRoute(
builder: (context) => CategoryScreen()));
},child: Text('Reset')),);
}
}
AuthProvider.dart
class AuthProvider extends ChangeNotifier {
bool _isAuthenticated = false;
bool get isAuthenticated => _isAuthenticated;
set isAuthenticated(bool isAuth) {
_isAuthenticated = isAuth;
notifyListeners();
}
Future emailLogin(String email,String password) async {
isAuthenticated = true;
}
Future logout() async {
isAuthenticated = false;
}
}
如果我使用Provider.of<AuthProvider>(context).logout()
从主页注销,则工作正常。但是,如果我push
或pushReplacement
一条新路由并尝试从新路由注销(只是说我从首页导航到类别页面并尝试从那里注销),则不会重定向到LoginPage。如果我打印isAuthenticated
的值,它将打印false,但是使用者没有监听或至少没有对变量更改做出反应。
请不要将此问题标记为重复,我搜索了许多其他类似的问题,但没有一个适合我的情况。
编辑: CategoryScreen.dart
class CategoryScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: RaisedButton(
onPressed: () {
final auth = Provider.of<AuthProvider>(context,listen: false);
auth.logout();
// print(auth.isAuthenticated);
},child: Text('Category Logout'),);
}
}
解决方法
我想您的问题是您没有在Consumer
的{{1}}中将logout
用作home
。看看,如果它对您有用
main.dart
MaterialApp
由于// needs to listen to the changes,to make changes
home: Consumer<AuthProvider>(
builder: (context,authProvider,child){
return authProvider.isAuthenticated ? HomeScreen() : LoginScreen();
}
)
不在您的Consumer
中,即使更改了值,它也无法按照提供程序为您更新视图。