如何创建一个BlocListener,它可以访问MaterialApp上下文,从而听得井井有条? [英] How to create a BlocListener that can listen to all pages in flutter with access to MaterialApp context?

查看:71
本文介绍了如何创建一个BlocListener,它可以访问MaterialApp上下文,从而听得井井有条?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试创建一个 BlocListener ,该功能能够监听整个应用程序中的所有页面/路由,就像您可以访问 Bloc Provider (如果它们是在根级别定义的,例如下面的代码

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

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 上下文来显示对话框.

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. 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

My implementation of page routing which removes the stack, which is another cause of losing access to the 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?

  • 我在身份验证后专门使用它.您真的不希望用户在登录后能够按返回按钮,然后将用户重定向回登录页面,对吗?通常,返回按钮应在登录时隐藏/关闭应用程序.

我的 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中使用了它

and used it in my 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),我都可以通过

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

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

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

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

这篇关于如何创建一个BlocListener,它可以访问MaterialApp上下文,从而听得井井有条?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆