Я пытаюсь создать BlocListener
, который имеет возможность прослушивать все страницы / маршруты в приложении так же, как вы можете получить доступ к Bloc
или Provider
во всем приложении, если они определены на уровне root, как в приведенном ниже коде
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
. Однако в этом случае мне нужно, чтобы указанный c слушатель (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,
);
}
}
Есть ли другой способ обойти это?