2

I want to use GoRouter to navigate through my app. I also want my App to be able to navigate on every platform, so I am using push / go depending on the platform.

Now I have specified these routes so far:

class Routes {
  static const String home = "/";
  static const String collectible = "/collectible";
  static const String scanner = "/scanner";
  static const String settings = "/settings";
  static const String settingsThemes = "/settings/themes";

  static GoRouter getRouter(Settings settings) {
    CustomTransitionPage<Widget> Function(GoRouterState state, Widget child) function = noTransitionAnimation;
    if (!kIsWeb && Platform.isAndroid) {
      function = fadeTransitionAnimation;
    }

    if (!kIsWeb && Platform.isIOS) {
      function = cupertinoTransitionAnimation;
    }

    return GoRouter(
      routes: [
        GoRoute(
          path: Routes.home,
          pageBuilder: (context, state) => function(state, HomeMenu(settings: settings)),
        ),
        GoRoute(
            path: "${Routes.collectible}/:category",
            pageBuilder: (context, state) {
              String category = state.params['category'] ?? "";
              return function(
                  state,
                  CollectibleTabListScreen(
                    category: category,
                    settings: settings,
                  ));
            }),
        GoRoute(
          path: Routes.scanner,
          pageBuilder: (context, state) => function(state, const ScannerScreen()),
        ),
        GoRoute(
          path: Routes.settings,
          pageBuilder: (context, state) => function(state, const SettingsScreen()),
        ),
        GoRoute(
          path: Routes.settingsThemes,
          pageBuilder: (context, state) => function(state, const ThemeSettingsScreen()),
        ),
      ],
      errorBuilder: (context, state) => RoutingErrorScreen(exception: state.error),
    );
  }

  static CustomTransitionPage<CupertinoPageTransition> cupertinoTransitionAnimation(GoRouterState state, Widget child) {
    return CustomTransitionPage(
      key: state.pageKey,
      child: child,
      transitionsBuilder: (context, animation, secondaryAnimation, child) {
        return CupertinoPageTransition(
          primaryRouteAnimation: animation,
          secondaryRouteAnimation: secondaryAnimation,
          linearTransition: true,
          child: child,
        );
      },
    );
  }

  static NoTransitionPage<Widget> noTransitionAnimation(GoRouterState state, Widget child) {
    return NoTransitionPage(
      key: state.pageKey,
      child: child,
    );
  }

  static CustomTransitionPage<FadeTransition> fadeTransitionAnimation(GoRouterState state, Widget child) {
    return CustomTransitionPage(
      key: state.pageKey,
      child: child,
      transitionsBuilder: (context, animation, secondaryAnimation, child) {
        // Change the opacity of the screen using a Curve based on the the animation's
        // value
        return FadeTransition(
          opacity: CurveTween(curve: Curves.easeInOutCirc).animate(animation),
          child: child,
        );
      },
    );
  }

My problem is that if I navigate to a page and back, I just straight up get the Exception: "Looking up a deactivated widget's ancestor is unsafe." and my App wont navigate anymore.

These are the first lines of the stack:

══╡ EXCEPTION CAUGHT BY GESTURE ╞═══════════════════════════════════════════════════════════════════
The following assertion was thrown while handling a gesture:
Looking up a deactivated widget's ancestor is unsafe.
At this point the state of the widget's element tree is no longer stable.
To safely refer to a widget's ancestor in its dispose() method, save a reference to the ancestor by
calling dependOnInheritedWidgetOfExactType() in the widget's didChangeDependencies() method.
When the exception was thrown, this was the stack:
C:/b/s/w/ir/cache/builder/src/out/host_debug/dart-sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/errors.dart 266:49      throw_
packages/flutter/src/widgets/framework.dart 4334:9                                                                             <fn>
packages/flutter/src/widgets/framework.dart 4347:14                                                                            [_debugCheckStateIsActiveForAncestorLookup]
packages/flutter/src/widgets/framework.dart 4368:12                                                                            dependOnInheritedWidgetOfExactType
packages/go_router/src/router.dart 362:16                                                                                      of
packages/go_router/src/misc/extensions.dart 23:25                                                                              GoRouterHelper.go

As you can see in the logs, I am already calling the method to depend on other widgets of the same type via context.dependOnInheritedWidgetOfExactType();, so I don't think that this is the real issue here.

All widgets listed on the routes are stateful widgets. In the CollectibleTabListScreen I use dispose() and it gets called properly, but why does the state not get re-initialized after being disposed?

How can I fix this issue?

Salatgurke
  • 1,554
  • 1
  • 13
  • 35

0 Answers0