Why onPopPage is not being trigger in flutter Navigator 2.0?

Viewed 329

When the back button is pressed instead of updating the state and screen the app is exited. I copied this logic from Flutter Apperenties. The same logic is working fine in another project.

I can't find the mistake. I tried to print inside _handlePopPage method but the app exits and it won't print. I think onPopPage is not being triggered.

here is my code,

class AppRouter extends RouterDelegate
    with ChangeNotifier, PopNavigatorRouterDelegateMixin {
  @override
  final GlobalKey<NavigatorState> navigatorKey;
  final AppState appStateManager;
  final ProvinceProvider provinceProvider;
  AppRouter({
    Key? key,
    required this.appStateManager,
    required this.provinceProvider,
  }) : navigatorKey = GlobalKey<NavigatorState>() {
    appStateManager.addListener(notifyListeners);
    provinceProvider.addListener(notifyListeners);
  }
  @override
  void dispose() {
    appStateManager.removeListener(notifyListeners);
    provinceProvider.removeListener(notifyListeners);
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Navigator(
      key: navigatorKey,
      pages: [
        if (!appStateManager.isInitialized) SplashScreen.page(),
        if (appStateManager.isInitialized &&
            appStateManager.currentPage == CurrentPagePointer.dashboardScreen)
          DashboardScreen.page(),
        if (appStateManager.currentPage ==
            CurrentPagePointer.openeingInformationScreen)
          OpeningInformationScreen.page(),
        if (appStateManager.currentPage == CurrentPagePointer.rQ1aScreen)
          RQ1aScreen.page(),
        if (appStateManager.currentPage == CurrentPagePointer.rQ1bScreen)
          RQ1bScreen.page(),
        if (appStateManager.currentPage == CurrentPagePointer.rQ1cScreen)
          RQ1cScreen.page(),
        if (appStateManager.currentPage == CurrentPagePointer.rQ1dScreen)
          RQ1dScreen.page(),
        if (appStateManager.currentPage == CurrentPagePointer.rQ1eScreen)
          RQ1eScreen.page(),
        if (appStateManager.currentPage == CurrentPagePointer.thankYouScreen)
          ThankYouScreen.page(),
      ],
      onPopPage: _handlePopPage,
    );
  }

  bool _handlePopPage(Route<dynamic> route, result) {
    if (!route.didPop(result)) {
      return false;
    }
    if (route.settings.name == MaxMediaPages.openeingInformationScreen) {
      print(route.settings.name);
      appStateManager.setCurrentPage(CurrentPagePointer.dashboardScreen);
      provinceProvider.resetData();
    }
    if (route.settings.name == MaxMediaPages.thankYouScreen) {
      print(route.settings.name);
      appStateManager.setCurrentPage(CurrentPagePointer.dashboardScreen);
    }
    return true;
  }

  @override
  Future<void> setNewRoutePath(configuration) async {}
}
2 Answers

The first page must be only "SplashScreen.page(),": without previous condition

You probably solved this by now, but for others who encounter the same problem, please check your main.dart or the class where you call MaterialApp (and Router). It has to have a parameter: backButtonDispatcher: RootBackButtonDispatcher(),

In my case it looks like this:

Widget build(BuildContext context) {
    return MultiProvider(
        providers: [
            ChangeNotifierProvider(
                create: (context) => _rallyManager,
            ),
            ChangeNotifierProvider(
                create: (context) => _positionManager,
            ),
            ChangeNotifierProvider(
                create: (context) => _appStateManager,
            )
        ],
        child: MaterialApp(
            title: 'MyApp',
            home: Router(
                routerDelegate: _appRouter,
                backButtonDispatcher: RootBackButtonDispatcher(),
            ),
        ),
    );
}
Related