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?