我正在尝试创建一个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,
);
}
}
有什么不同的方法吗?
发布于 2020-04-18 13:41:31
所以我最终定义了一个
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之外的情况下导航时(在我的例子中,通过根级别上的AuthListener,在MaterialApp之上),我可以通过
App.navigatorKey.currentState.pushAndRemoveUntil(
MaterialPageRoute(builder: (_) => route),
(Route<dynamic> route) => false);
这意味着我最终可以访问MaterialApp导航器和上下文,即使在MaterialApp之外的侦听器中也是如此,这允许我同时进行导航和显示对话框。
https://stackoverflow.com/questions/61295539
复制