颤抖什么是将导航器和ChangeNotifierProvider一起使用的最佳方法

时间:2020-09-30 00:43:35

标签: flutter flutter-provider flutter-navigation flutter-change-notifier

我是新手,这个问题可能是一个非常基本的问题。 我有一个Firebase电话身份验证登录页面来实现此目的, 如果用户已登录,则导航到主页 否则,如果该用户是新用户,则导航至注册页面

问题在于,每当在提供者处更改值时,使用者都会得到通知并重建生成方法。我将无法在build方法中收听它们并返回Navigator.of(context).pushNamed()。知道使用ChangeNotifierProvider以及侦听器和相应页面导航的正确方法是什么吗?

我有如下的Login类和provider类,

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();
        },
          ...
         );
    }
}

谢谢。

1 个答案:

答案 0 :(得分:1)

有几种方法,您可以选择最适合自己的方法。

  1. context传递到ChangeNotifier,就像已经做的那样。我也不喜欢这样,但是有些人喜欢。

  2. 向您的ChangeNotifier传递回调,当您需要导航时会被调用。此回调将由您的UI代码执行。

  3. 与2相同,但是代替回调输出Stream并发出一个事件,指示您需要导航。然后,您只需在用户界面上收听Stream并从那里导航即可。

  4. 使用GlobalKey用于导航器,然后将其传递到MaterialApp,这样您就可以在任何地方使用此键。更多详细信息here