Search code examples
flutterflutter-go-router

Go router ShellRoute for widget is resulting in error


I'm trying to build a website with a top navbar, content and a footer. I am using go router to navigate between different page content while retaining the navbar and footer.

This is my implementation, but I'm getting a blank screen with this log:

Go router file

final GlobalKey<NavigatorState> rootNavigatorKey =
    GlobalKey<NavigatorState>(debugLabel: 'root');

final GlobalKey<NavigatorState> shellNavigatorKey =
    GlobalKey<NavigatorState>(debugLabel: 'shell');

final GoRouter appRouter = GoRouter(
  navigatorKey: rootNavigatorKey,
  initialLocation: '/',
  debugLogDiagnostics: true,
  routes: <RouteBase>[
    ShellRoute(
      navigatorKey: shellNavigatorKey,
      builder: (BuildContext context, GoRouterState state, Widget child) {
        return HomeScreen(
          key: state.pageKey,
          pageContent: child, // <--- Passing the pageContent Widget to HomeScreen Widget 
        );
      },
      routes: <RouteBase>[
        GoRoute(
          name: 'home',
          path: '/',
          builder: (BuildContext context, GoRouterState state) {
            return const HomePageContent();
          },
        ),
        GoRoute(
          path: '/about',
          name: 'about',
          builder: (BuildContext context, GoRouterState state) {
            return const AboutPageContent();
          },
        ),
        GoRoute(
          path: '/contact',
          name: 'contact',
          builder: (BuildContext context, GoRouterState state) {
            return const ContactPageContent();
          },
        ),
      ],
    )
  ],
);

HomeScreen file

class HomeScreen extends StatefulWidget {
  final Widget pageContent;

  const HomeScreen({super.key, required this.pageContent});

  @override
  State<HomeScreen> createState() => _HomeScreenState();
}

class _HomeScreenState extends State<HomeScreen> {
  @override
  Widget build(BuildContext context) {
    w = MediaQuery.of(context).size.width;
    h = MediaQuery.of(context).size.height;
    return Scaffold(
      appBar: NavBar(),
      body: Body(
        pageContent: widget.pageContent, // <--- Passing the pageContent Widget to Body widget
      ),
    );
  }
}

Body widget file

class Body extends StatefulWidget {
  final Widget pageContent;
  const Body({super.key, required this.pageContent});
  
@override
  State<Body> createState() => _BodyState();
}

class _BodyState extends State<Body> {
  @override
  Widget build(BuildContext context) {
    return SingleChildScrollView(
      child: ScreenTypeLayout.builder( // Responsive layout using flutter_responsive_builder
        mobile: (context) => mobileBody(),
        tablet: (context) => tabletBody(),
        desktop: (context) => desktopBody(),
      ),
    );
  }
  
  ...

  Widget desktopBody() {
    bodyMarginWidth = w! / 6;
    return Padding(
      padding: EdgeInsets.symmetric(
        horizontal: bodyMarginWidth!,
        vertical: 25,
      ),
      child: Column(
        children: [
          widget.pageContent, // <--- Using the pageContent widget
          horizontalLine(),
          Footer(),
        ],
      ),
    );
  }
  ...
}

HomePageContent file

class HomePageContent extends StatefulWidget {
  const HomePageContent({super.key});

  @override
  State<HomePageContent> createState() => _HomePageContentState();
}

class _HomePageContentState extends State<HomePageContent> {
  @override
  Widget build(BuildContext context) {
    return Container(
      width: w! - 2 * bodyMarginWidth!, // dynamic width for mobile and desktop views
      color: Colors.lime[100], // fill color
      height: h! * 2,
    );
  }
}

Debug Console

=═╡ EXCEPTION CAUGHT BY RENDERING LIBRARY ╞═════════════════════════════════════════════════════════
The following assertion was thrown during performResize():
Assertion failed:
overlay.dart:1064
constraints.biggest.isFinite
is not true
The relevant error-causing widget was:
  Navigator-[LabeledGlobalKey<NavigatorState>#433fa shell]
Navigator:file:///C:/Users/laksh/AppData/Local/Pub/Cache/hosted/pub.dev/go_router-9.0.3/lib/src/builder.dart:302:30
builder.dart:302
When the exception was thrown, this was the stack:
dart-sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/errors.dart 288:49  throw_
dart-sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/errors.dart 29:3    assertFailed
packages/flutter/src/widgets/overlay.dart 1064:23                             computeDryLayout
packages/flutter/src/rendering/box.dart 2397:12                               performResize
packages/flutter/src/rendering/object.dart 2374:9                             layout
packages/flutter/src/rendering/box.dart 2386:11                               layout
packages/flutter/src/rendering/proxy_box.dart 122:7                           performLayout
packages/flutter/src/rendering/object.dart 2395:7                             layout
packages/flutter/src/rendering/box.dart 2386:11                               layout
packages/flutter/src/rendering/proxy_box.dart 122:7                           performLayout
packages/flutter/src/rendering/object.dart 2395:7                             layout
packages/flutter/src/rendering/box.dart 2386:11                               layout
packages/flutter/src/rendering/layout_helper.dart 52:10                       layoutChild
packages/flutter/src/rendering/flex.dart 808:43                               [_computeSizes]
packages/flutter/src/rendering/flex.dart 903:32                               performLayout
packages/flutter/src/rendering/object.dart 2395:7                             layout
packages/flutter/src/rendering/box.dart 2386:11                               layout
packages/flutter/src/rendering/shifted_box.dart 238:5                         performLayout
packages/flutter/src/rendering/object.dart 2395:7                             layout
packages/flutter/src/rendering/box.dart 2386:11                               layout
packages/flutter/src/widgets/layout_builder.dart 315:7                        performLayout
packages/flutter/src/rendering/object.dart 2395:7                             layout
packages/flutter/src/rendering/box.dart 2386:11                               layout
packages/flutter/src/widgets/single_child_scroll_view.dart 491:7              performLayout
packages/flutter/src/rendering/object.dart 2395:7                             layout
packages/flutter/src/rendering/box.dart 2386:11                               layout
packages/flutter/src/rendering/proxy_box.dart 122:7                           performLayout
packages/flutter/src/rendering/object.dart 2395:7                             layout
packages/flutter/src/rendering/box.dart 2386:11                               layout
packages/flutter/src/rendering/proxy_box.dart 122:7                           performLayout
packages/flutter/src/rendering/object.dart 2395:7                             layout
packages/flutter/src/rendering/box.dart 2386:11                               layout
...
packages/flutter/src/rendering/proxy_box.dart 122:7                           performLayout
packages/flutter/src/rendering/object.dart 2395:7                             layout
packages/flutter/src/rendering/box.dart 2386:11                               layout
packages/flutter/src/rendering/proxy_box.dart 122:7                           performLayout
packages/flutter/src/rendering/object.dart 2395:7                             layout
packages/flutter/src/rendering/box.dart 2386:11                               layout
packages/flutter/src/rendering/view.dart 173:7                                performLayout
packages/flutter/src/rendering/object.dart 2234:7                             [_layoutWithoutResize]
packages/flutter/src/rendering/object.dart 1016:17                            flushLayout
packages/flutter/src/rendering/binding.dart 492:19                            drawFrame
packages/flutter/src/widgets/binding.dart 905:13                              drawFrame
packages/flutter/src/rendering/binding.dart 358:5                             [_handlePersistentFrameCallback]
packages/flutter/src/scheduler/binding.dart 1284:15                           [_invokeFrameCallback]
packages/flutter/src/scheduler/binding.dart 1214:9                            handleDrawFrame
packages/flutter/src/scheduler/binding.dart 939:7                             <fn>
dart-sdk/lib/_internal/js_dev_runtime/private/isolate_helper.dart 48:19       internalCallback
The following RenderObject was being processed when the exception was fired: _RenderTheater#65a84 NEEDS-LAYOUT NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE:
  creator: _Theater ← Overlay-[LabeledGlobalKey<OverlayState>#e4f12] ← UnmanagedRestorationScope ←
    _FocusInheritedScope ← Focus ← _FocusInheritedScope ← Focus ← FocusTraversalGroup ← AbsorbPointer
    ← Listener ← HeroControllerScope ← Navigator-[LabeledGlobalKey<NavigatorState>#433fa shell] ← ⋯
  parentData: <none> (can use size)
  constraints: BoxConstraints(0.0<=w<=1138.2, 0.0<=h<=Infinity)
  size: MISSING
  skipCount: 0
  textDirection: ltr
This RenderObject had the following descendants (showing up to depth 5):
    onstage 1: RenderIgnorePointer#1f0c9 NEEDS-LAYOUT NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE
      child: RenderBlockSemantics#c664d NEEDS-LAYOUT NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE
        child: RenderExcludeSemantics#67745 NEEDS-LAYOUT NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE
          child: RenderSemanticsGestureHandler#6bde9 NEEDS-LAYOUT NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE
            child: RenderPointerListener#48c06 NEEDS-LAYOUT NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE
    onstage 2: RenderSemanticsAnnotations#4df60 NEEDS-LAYOUT NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE
      child: RenderOffstage#baa8d NEEDS-LAYOUT NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE
        child: RenderSemanticsAnnotations#d5360 NEEDS-LAYOUT NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE
          child: RenderRepaintBoundary#8c24e NEEDS-LAYOUT NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE
            child: _RenderSnapshotWidget#10fa7 NEEDS-LAYOUT NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE
    no offstage children
════════════════════════════════════════════════════════════════════════════════════════════════════
Another exception was thrown: BoxConstraints forces an infinite height.
23
Another exception was thrown: Assertion failed:
box.dart:1966
14
Another exception was thrown: Cannot hit test a render box that has never been laid out.

There is no error, if in gorouter file I provide HomePageContent() directly to the pageContent named parameter of HomeScreen() in the builder.


Solution

  • The problem was in my approach. The HomePageContent relies on parent constraints which were getting messed up.

    Rewrote the whole thing and now swapping the entire scaffold body instead of one certain element.