我正在尝试创建一个BlocListener
,使其能够侦听整个应用程序中的所有页面/路由,就像您可以在整个应用程序中访问Bloc
或Provider
的方式一样(如果它们是在根级别定义的,例如下面的代码)
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导航器和上下文,这使我既可以导航又可以显示对话框