@@ -498,8 +498,17 @@ abstract class ShellRouteBase extends RouteBase {
498498 super .redirect,
499499 required super .routes,
500500 required super .parentNavigatorKey,
501+ this .notifyRootObserver = true ,
501502 }) : super ._();
502503
504+ /// Whether navigation changes will notify the GoRouter's observers.
505+ ///
506+ /// When `true` , navigation changes within this shell route will notify
507+ /// the GoRouter's observers.
508+ ///
509+ /// Defaults to `true` .
510+ final bool notifyRootObserver;
511+
503512 static void _debugCheckSubRouteParentNavigatorKeys (
504513 List <RouteBase > subRoutes,
505514 GlobalKey <NavigatorState > navigatorKey,
@@ -577,14 +586,28 @@ class ShellRouteContext {
577586 final NavigatorBuilder navigatorBuilder;
578587
579588 Widget _buildNavigatorForCurrentRoute (
589+ BuildContext context,
580590 List <NavigatorObserver >? observers,
591+ bool notifyRootObserver,
581592 String ? restorationScopeId,
582593 ) {
594+ final List <NavigatorObserver > effectiveObservers = < NavigatorObserver > [
595+ ...? observers,
596+ ];
597+
598+ if (notifyRootObserver) {
599+ final List <NavigatorObserver >? rootObservers =
600+ GoRouter .maybeOf (context)? .observers;
601+ if (rootObservers != null ) {
602+ effectiveObservers.add (_MergedNavigatorObserver (rootObservers));
603+ }
604+ }
605+
583606 return navigatorBuilder (
584607 navigatorKey,
585608 match,
586609 routeMatchList,
587- observers ,
610+ effectiveObservers ,
588611 restorationScopeId,
589612 );
590613 }
@@ -691,6 +714,7 @@ class ShellRoute extends ShellRouteBase {
691714 super .redirect,
692715 this .builder,
693716 this .pageBuilder,
717+ super .notifyRootObserver,
694718 this .observers,
695719 required super .routes,
696720 super .parentNavigatorKey,
@@ -732,7 +756,9 @@ class ShellRoute extends ShellRouteBase {
732756 ) {
733757 if (builder != null ) {
734758 final Widget navigator = shellRouteContext._buildNavigatorForCurrentRoute (
759+ context,
735760 observers,
761+ notifyRootObserver,
736762 restorationScopeId,
737763 );
738764 return builder !(context, state, navigator);
@@ -748,7 +774,9 @@ class ShellRoute extends ShellRouteBase {
748774 ) {
749775 if (pageBuilder != null ) {
750776 final Widget navigator = shellRouteContext._buildNavigatorForCurrentRoute (
777+ context,
751778 observers,
779+ notifyRootObserver,
752780 restorationScopeId,
753781 );
754782 return pageBuilder !(context, state, navigator);
@@ -870,6 +898,7 @@ class StatefulShellRoute extends ShellRouteBase {
870898 super .redirect,
871899 this .builder,
872900 this .pageBuilder,
901+ super .notifyRootObserver,
873902 required this .navigatorContainerBuilder,
874903 super .parentNavigatorKey,
875904 this .restorationScopeId,
@@ -900,6 +929,7 @@ class StatefulShellRoute extends ShellRouteBase {
900929 /// for a complete runnable example using StatefulShellRoute.indexedStack.
901930 StatefulShellRoute .indexedStack ({
902931 required List <StatefulShellBranch > branches,
932+ bool notifyRootObserver = true ,
903933 GoRouterRedirect ? redirect,
904934 StatefulShellRouteBuilder ? builder,
905935 GlobalKey <NavigatorState >? parentNavigatorKey,
@@ -911,6 +941,7 @@ class StatefulShellRoute extends ShellRouteBase {
911941 redirect: redirect,
912942 builder: builder,
913943 pageBuilder: pageBuilder,
944+ notifyRootObserver: notifyRootObserver,
914945 parentNavigatorKey: parentNavigatorKey,
915946 restorationScopeId: restorationScopeId,
916947 navigatorContainerBuilder: _indexedStackContainerBuilder,
@@ -1422,7 +1453,9 @@ class StatefulNavigationShellState extends State<StatefulNavigationShell>
14221453 previousBranchLocation != currentBranchLocation;
14231454 if (locationChanged || ! hasExistingNavigator) {
14241455 branchState.navigator = shellRouteContext._buildNavigatorForCurrentRoute (
1456+ context,
14251457 branch.observers,
1458+ route.notifyRootObserver,
14261459 branch.restorationScopeId,
14271460 );
14281461 }
@@ -1674,3 +1707,67 @@ class _IndexedStackedRouteBranchContainer extends StatelessWidget {
16741707 );
16751708 }
16761709}
1710+
1711+ /// A wrapper that merges multiple [NavigatorObserver] s into a single observer.
1712+ ///
1713+ /// This is necessary because a [NavigatorObserver] can only be attached to one
1714+ /// [NavigatorState] at a time.
1715+ class _MergedNavigatorObserver extends NavigatorObserver {
1716+ /// Default constructor for the merged navigator observer.
1717+ _MergedNavigatorObserver (this .observers);
1718+
1719+ /// The observers to be merged.
1720+ final List <NavigatorObserver > observers;
1721+
1722+ @override
1723+ void didPush (Route <dynamic > route, Route <dynamic >? previousRoute) {
1724+ for (final NavigatorObserver observer in observers) {
1725+ observer.didPush (route, previousRoute);
1726+ }
1727+ }
1728+
1729+ @override
1730+ void didPop (Route <dynamic > route, Route <dynamic >? previousRoute) {
1731+ for (final NavigatorObserver observer in observers) {
1732+ observer.didPop (route, previousRoute);
1733+ }
1734+ }
1735+
1736+ @override
1737+ void didRemove (Route <dynamic > route, Route <dynamic >? previousRoute) {
1738+ for (final NavigatorObserver observer in observers) {
1739+ observer.didRemove (route, previousRoute);
1740+ }
1741+ }
1742+
1743+ @override
1744+ void didReplace ({Route <dynamic >? newRoute, Route <dynamic >? oldRoute}) {
1745+ for (final NavigatorObserver observer in observers) {
1746+ observer.didReplace (newRoute: newRoute, oldRoute: oldRoute);
1747+ }
1748+ }
1749+
1750+ @override
1751+ void didChangeTop (Route <dynamic > topRoute, Route <dynamic >? previousTopRoute) {
1752+ for (final NavigatorObserver observer in observers) {
1753+ observer.didChangeTop (topRoute, previousTopRoute);
1754+ }
1755+ }
1756+
1757+ @override
1758+ void didStartUserGesture (
1759+ Route <dynamic > route,
1760+ Route <dynamic >? previousRoute,
1761+ ) {
1762+ for (final NavigatorObserver observer in observers) {
1763+ observer.didStartUserGesture (route, previousRoute);
1764+ }
1765+ }
1766+
1767+ @override
1768+ void didStopUserGesture () {
1769+ for (final NavigatorObserver observer in observers) {
1770+ observer.didStopUserGesture ();
1771+ }
1772+ }
1773+ }
0 commit comments