Flutter 一起使用 navigator 和 ChangeNotifierProvider 的最佳方法是什么
Flutter what is the best approach to use navigator and ChangeNotifierProvider together
我是 Flutter 新手,这个问题可能是一个非常基础的问题。
我有一个 firebase phone 授权登录页面来实现这个,
如果用户已登录,则导航到主页
否则如果用户是新用户,则导航到注册页面
问题是,无论何时更改提供者的值,消费者都会收到通知并重建构建方法。我将无法在构建方法和 return a Navigator.of(context).pushNamed() 中收听它们。知道将 ChangeNotifierProvider 与侦听器和相应的页面导航一起使用的正确方法是什么吗?
我的登录名 class 和供应商 class 如下,
class LoginPage extends StatefulWidget {
@override
_LoginPageState createState() => _LoginPageState();
}
class _LoginPageState extends State<LoginPage> {
@override
Widget build(BuildContext context) {
return ChangeNotifierProvider(
create: (_) => LoginProvider(),
child: Consumer<LoginProvider>(builder: (context, loginState, child) {
return Scaffold(
...
body: RaisedButton(
onPressed: **loginState.doLogin(_textController.text, context);**
...
)
}),
);
}
}
class LoginProvider with ChangeNotifier {
bool _navigateToSignup = false;
bool get navigateToSignup => _navigateToSignup;
Future doLogin(String mobile, BuildContext context) async {
FirebaseAuth _auth = FirebaseAuth.instance;
_auth.verifyPhoneNumber(
...
verificationCompleted: (AuthCredential credential) async {
UserCredential result = await _auth.signInWithCredential(credential);
User user = result.user;
// if user is new user navigate to signup
// do not want to use Navigator.of(context).pushNamed('/signupPage'); here, instead would like to notify listeners at login page view and then use navigator.
if (user.metadata.creationTime == user.metadata.lastSignInTime) {
_navigateToSignup = true;
} else {
if (result.user != null) {
_navigateToHome = true;
//Navigator.of(context).pushNamedAndRemoveUntil('/homePage', ModalRoute.withName('/'));
}
}
notifyListeners();
},
...
);
}
}
提前致谢。
有多种方法,您选择最适合自己的一种。
像您已经在做的那样将 context
传递给 ChangeNotifier
。我也不喜欢这样,但是有人这样做。
将回调传递给您的 ChangeNotifier
,当您需要导航时将调用该回调。此回调将由您的 UI 代码执行。
与 2 相同,但不是回调导出 Stream
并发出指示您需要导航的事件。然后你只需在 UI 上收听 Stream
并从那里导航。
为您的导航器使用 GlobalKey
并将其传递给您的 MaterialApp
,这样您就可以在任何地方使用此密钥。更多详情 here.
我是 Flutter 新手,这个问题可能是一个非常基础的问题。 我有一个 firebase phone 授权登录页面来实现这个, 如果用户已登录,则导航到主页 否则如果用户是新用户,则导航到注册页面
问题是,无论何时更改提供者的值,消费者都会收到通知并重建构建方法。我将无法在构建方法和 return a Navigator.of(context).pushNamed() 中收听它们。知道将 ChangeNotifierProvider 与侦听器和相应的页面导航一起使用的正确方法是什么吗?
我的登录名 class 和供应商 class 如下,
class LoginPage extends StatefulWidget {
@override
_LoginPageState createState() => _LoginPageState();
}
class _LoginPageState extends State<LoginPage> {
@override
Widget build(BuildContext context) {
return ChangeNotifierProvider(
create: (_) => LoginProvider(),
child: Consumer<LoginProvider>(builder: (context, loginState, child) {
return Scaffold(
...
body: RaisedButton(
onPressed: **loginState.doLogin(_textController.text, context);**
...
)
}),
);
}
}
class LoginProvider with ChangeNotifier {
bool _navigateToSignup = false;
bool get navigateToSignup => _navigateToSignup;
Future doLogin(String mobile, BuildContext context) async {
FirebaseAuth _auth = FirebaseAuth.instance;
_auth.verifyPhoneNumber(
...
verificationCompleted: (AuthCredential credential) async {
UserCredential result = await _auth.signInWithCredential(credential);
User user = result.user;
// if user is new user navigate to signup
// do not want to use Navigator.of(context).pushNamed('/signupPage'); here, instead would like to notify listeners at login page view and then use navigator.
if (user.metadata.creationTime == user.metadata.lastSignInTime) {
_navigateToSignup = true;
} else {
if (result.user != null) {
_navigateToHome = true;
//Navigator.of(context).pushNamedAndRemoveUntil('/homePage', ModalRoute.withName('/'));
}
}
notifyListeners();
},
...
);
}
}
提前致谢。
有多种方法,您选择最适合自己的一种。
像您已经在做的那样将
context
传递给ChangeNotifier
。我也不喜欢这样,但是有人这样做。将回调传递给您的
ChangeNotifier
,当您需要导航时将调用该回调。此回调将由您的 UI 代码执行。与 2 相同,但不是回调导出
Stream
并发出指示您需要导航的事件。然后你只需在 UI 上收听Stream
并从那里导航。为您的导航器使用
GlobalKey
并将其传递给您的MaterialApp
,这样您就可以在任何地方使用此密钥。更多详情 here.