简体   繁体   English

如何创建一个 BlocListener 可以监听 flutter 中的所有页面并访问 MaterialApp 上下文?

[英]How to create a BlocListener that can listen to all pages in flutter with access to MaterialApp context?

I'm trying to create a BlocListener that has the ability to listen to all pages/routes throughout the app just like how you can access a Bloc or a Provider all throughout the app if they are defined at root-level like in the code below我正在尝试创建一个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(),
          ),
        ),
      ),
    ),
  ),
);

As you can see, I have providers, blocs, and one listener.如您所见,我有提供者、集团和一名听众。 I have no problem accessing the blocs and providers in other pages.我在其他页面中访问集团和提供者没有问题。 My problem is the auth listener.我的问题是身份验证侦听器。 I lose access to the AuthListener once I move to a different page (by removing stack), because it is inside the MaterialApp .一旦我移动到不同的页面(通过删除堆栈),我将无法访问AuthListener ,因为它位于MaterialApp内。 However, in this instance, I need that specific listener ( AuthListener ) to be inside a MaterialApp , because it consists of code that uses page navigations (which doesn't work if the implementation is done outside/above the widget tree of a MaterialApp ), and makes us of the MaterialApp context for showing dialogs.但是,在这种情况下,我需要特定的侦听器( AuthListener )位于MaterialApp中,因为它包含使用页面导航的代码(如果实现是在MaterialApp的小部件树之外/之上完成的,则该代码不起作用) ,并使我们使用MaterialApp上下文来显示对话框。

My implementation of page routing which removes the stack, which is another cause of losing access to the AuthListener我的页面路由实现删除了堆栈,这是失去对AuthListener访问权限的另一个原因

Navigator.pushAndRemoveUntil(
        context,
        MaterialPageRoute(builder: (_) => route),
        (Route<dynamic> route) => false);

Why do I remove the route/page stack when moving to a different page?为什么在移动到不同页面时要删除路由/页面堆栈?

  • I specifically use this after authentication.我在身份验证后专门使用它。 You don't really want a user to be able to press back button after logging in, andredirect the user back to the login page right?您真的不希望用户在登录后能够按返回按钮,并将用户重定向回登录页面,对吗? Usually back button should hide/close the app when they are logged in.通常后退按钮应该在他们登录时隐藏/关闭应用程序。

My AuthListener implementation我的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,
    );
  }
}

Is there a different way around this?有没有不同的方法来解决这个问题?

So I ended up defining a所以我最终定义了一个

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

and used it in my MaterialApp并在我的 MaterialApp 中使用它

@override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: App.DEBUGGABLE,
      theme: ThemeData(
          // fontFamily: CustomFontStyle.montserrat,
          ),
      navigatorKey: App.navigatorKey,
      home: Center(
        child: const LoginPage(),
      ),
    );
  }

So then, whenever I have to navigate in cases where the implementation is outside the MaterialApp (in my case via the AuthListener which is found at root-level, above the MaterialApp), I can navigate via因此,每当我必须在实现位于 MaterialApp 之外的情况下进行导航(在我的情况下,通过在 MaterialApp 上方的根级别找到的 AuthListener),我可以通过

App.navigatorKey.currentState.pushAndRemoveUntil(
            MaterialPageRoute(builder: (_) => route),
            (Route<dynamic> route) => false);

Which means I can finally have access to the MaterialApp navigator and context even with the listener outside the MaterialApp which allows me to do both navigation and showing of dialogs这意味着我终于可以访问 MaterialApp 导航器和上下文,即使在 MaterialApp 之外的侦听器也允许我进行导航和显示对话框

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何使用 flutter 在 MaterialApp 中创建卡片 - How create a card in MaterialApp using flutter Flutter Cubit 与 BlocListener:如何根据 state 导航用户? - Flutter Cubit With BlocListener: How can I Navigate the user according to state? 在MaterialApp外部访问Flutter路线 - Access Flutter route outside MaterialApp Flutter MaterialApp-如何使用AppBar标题作为链接 - Flutter MaterialApp - How can I use the AppBar title as a link Flutter App中如何正确使用BlocListener和BlocProvider - How to correctly use BlocListener and BlocProvider in Flutter App Flutter:如何制作 MaterialApp RouteAware - Flutter: How to make a MaterialApp RouteAware 我们如何在 flutter 中不添加上下文的情况下推送到各个页面? - How can we push to various pages without adding context in flutter? Flutter - 使用 MultiBlocProvider 但无法在子屏幕上呈现 BlocListener - Flutter - using MultiBlocProvider but can't render BlocListener at sub screen 如何在 MaterialApp 级别定义媒体查询,以便它可以应用于 Flutter 中的所有屏幕/脚手架? - How to define media query at MaterialApp level, so that it could be applied to all screens/scaffold in flutter? 使用 MaterialApp.router() 时 Flutter 中的全局上下文 - Global context in Flutter while using MaterialApp.router()
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM