[英]How to create a BlocListener that can listen to all pages in flutter with access to MaterialApp context?
我正在嘗試創建一個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 之外的偵聽器也允許我進行導航和顯示對話框
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.