为什么 flutter Navigator 2.0 中没有触发 onPopPage?

发布于 2025-01-11 01:52:17 字数 2650 浏览 0 评论 0原文

当按下后退按钮而不是更新状态和屏幕时,应用程序将退出。我从 Flutter Apperenties 复制了这个逻辑。同样的逻辑在另一个项目中运行良好。

我找不到错误。我尝试在 _handlePopPage 方法内部打印,但应用程序退出并且不会打印。我认为 onPopPage 没有被触发。

这是我的代码,

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 {}
}

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 {}
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

向地狱狂奔 2025-01-18 01:52:17

第一页必须仅为“SplashScreen.page(),”:无先前条件

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

空城仅有旧梦在 2025-01-18 01:52:17

您现在可能已经解决了这个问题,但是对于遇到相同问题的其他人,请检查您的 main.dart 或调用 MaterialApp (和 Router)的类。它必须有一个参数: backButtonDispatcher: RootBackButtonDispatcher(),

在我的例子中,它看起来像这样:

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(),
            ),
        ),
    );
}

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(),
            ),
        ),
    );
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文