我正在尝试创建一个BlocListener,使其能够侦听整个应用程序中的所有页面/路由,就像您可以在整个应用程序中访问BlocProvider的方式一样(如果它们是在根级别定义的,例如下面的代码)

runApp(
  MultiProvider(
    providers: [
      ChangeNotifierProvider<IdentityTokenProvider>(
        create: (_) => IdentityTokenProvider(),
      ),
    ],
    child: MultiBlocProvider(
      providers: [
        BlocProvider<AuthBloc>(
          create: (_) => AuthBloc(),
        ),
      ],
      child: MaterialApp(
        debugShowCheckedModeBanner: AppConfig.DEBUGGABLE,
        theme: ThemeData(
            // fontFamily: CustomFontStyle.montserrat,
            ),
        home: AuthListener(
          child: Center(
            child: const MainApp(),
          ),
        ),
      ),
    ),
  ),
);

如您所见,我有提供者,集团和一个侦听器。访问其他页面中的集团和提供者,我没有问题。我的问题是授权侦听器。一旦移至其他页面(通过删除堆栈),我就无法访问AuthListener,因为它位于MaterialApp内。但是,在这种情况下,我需要将特定的侦听器(AuthListener)放在MaterialApp内,因为它由使用页面导航的代码组成(如果实现是在MaterialApp的小部件树外部/上方完成,则不起作用) ,并利用MaterialApp上下文显示对话框。

我的页面路由实现删除了堆栈,这是导致无法访问AuthListener的另一个原因
Navigator.pushAndRemoveUntil(
        context,
        MaterialPageRoute(builder: (_) => route),
        (Route<dynamic> route) => false);

为什么移至其他页面时删除路线/页面堆栈?
  • 我在身份验证后专门使用了它。您真的不希望用户在登录后能够按返回按钮,然后将用户重定向回登录页面,对吗?通常,返回按钮应在登录时隐藏/关闭应用程序。

  • 我的AuthListener实现
    class AuthListener extends StatefulWidget {
      final Widget child;
    
      const AuthListener({Key key, @required this.child}) : super(key: key);
    
      @override
      _AuthListenerState createState() => _AuthListenerState();
    }
    
    class _AuthListenerState extends State<AuthListener> {
      @override
      Widget build(BuildContext context) {
        return BlocListener<AuthBloc, AuthState>(
          listener: (context, state) {
            if (state is AuthAuthenticated) {
              PageRouterController.pushAndRemoveStack(context, const EcomPage());
            } else if (state is AuthUnauthenticated) {
              PageRouterController.pushAndRemoveStack(context, const LoginPage());
            }
          },
          child: widget.child,
        );
      }
    }
    

    有其他解决方法吗?

    最佳答案

    所以我最终定义了

    static final GlobalKey<NavigatorState> navigatorKey = new GlobalKey();
    

    并在我的MaterialApp中使用了它
    @override
      Widget build(BuildContext context) {
        return MaterialApp(
          debugShowCheckedModeBanner: App.DEBUGGABLE,
          theme: ThemeData(
              // fontFamily: CustomFontStyle.montserrat,
              ),
          navigatorKey: App.navigatorKey,
          home: Center(
            child: const LoginPage(),
          ),
        );
      }
    

    因此,每当我必须在实现不在MaterialApp的情况下进行导航时(对于我而言,是通过在MaterialApp上方的根级别找到的AuthListener),
    App.navigatorKey.currentState.pushAndRemoveUntil(
                MaterialPageRoute(builder: (_) => route),
                (Route<dynamic> route) => false);
    

    这意味着即使使用MaterialApp之外的侦听器,我最终也可以访问MaterialApp导航器和上下文,这使我既可以导航又可以显示对话框

    09-08 03:57