In Flutter Go_Router, the replace command to use routing to ShellRoute is not working properly

859 Views Asked by At

I'm trying to make a application that have a init page and nested routed page.

To do that, I use a go_router library.

Here is my code.

import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';

void main() => runApp(const MyApp());

final GlobalKey<NavigatorState> rootNavKey = GlobalKey<NavigatorState>();
final GlobalKey<NavigatorState> shellNavKey = GlobalKey<NavigatorState>();

final GoRouter router = GoRouter(
  navigatorKey: rootNavKey,
  initialLocation: '/',
  routes: [
    GoRoute(
      path: '/',
      pageBuilder: (context, state) => const NoTransitionPage(child: Home()),
    ),
    ShellRoute(
      navigatorKey: shellNavKey,
      routes: [
        GoRoute(
          path: '/somepage1',
          pageBuilder: (context, state) => const NoTransitionPage(child: SomePage1()),
        ),
        GoRoute(
          path: '/somepage2',
          pageBuilder: (context, state) => const NoTransitionPage(child: SomePage2()),
        ),
      ],
      builder: (context, state, child) => Shell(state: state, child: child),
    ),
  ],
);

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp.router(
      routerConfig: router,
    );
  }
}

class Shell extends StatelessWidget {
  Shell({super.key, required this.state, required this.child}) {
    print('Shell: ${state.location}');
  }

  final GoRouterState state;
  final Widget child;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Row(
        children: [
          Container(
            width: 300.0,
            color: Colors.black,
            padding: const EdgeInsets.all(16),
            child: Column(
              children: [
                ListTile(
                  onTap: () => context.go('/somepage1'),
                  title: const Text('Go to SomePage 1', style: TextStyle(color: Colors.white)),
                ),
                ListTile(
                  onTap: () => context.go('/somepage2'),
                  title: const Text('Go to SomePage 2', style: TextStyle(color: Colors.white)),
                ),
              ],
            ),
          ),
          Expanded(child: child),
        ],
      ),
    );
  }
}

class Home extends StatelessWidget {
  const Home({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: InkWell(
          onTap: () => context.replace('/somepage1'),
          child: const Text('Click!'),
        ),
      ),
    );
  }
}

class SomePage1 extends StatelessWidget {
  const SomePage1({super.key});

  @override
  Widget build(BuildContext context) {
    return const Scaffold(
      body: Center(
        child: Text('Some Page 1'),
      ),
    );
  }
}

class SomePage2 extends StatelessWidget {
  const SomePage2({super.key});

  @override
  Widget build(BuildContext context) {
    return const Scaffold(
      body: Center(
        child: Text('Some Page 2'),
      ),
    );
  }
}

When you clicked the text in the init page, you can go to the nested page that I want to go - somepage1.

But there are some strange point have a gap with my purpose.

My purposes are these.

  1. When I go to nested page, the nested page have to be an only page.
  2. When the nested page was built, the parent widget Shell have to be built also.

But these two purposes are not satisfied.

  1. When I went to nested page, the previous page was not popped.
  2. When the nested page was build, the parent widget Shell was not built.

To solve this issue, what should I do...?

0

There are 0 best solutions below