flutterflutter-go-routergorouter

On Flutter go_router how to change only content of special container?


I have a page in Flutter which has 3 different elements header, sidebar and main_content. Sidebar contains some text buttons login, customer, manager etc.

When someone clicks on the button on the sidebar i want to change only the content of the main_content. I dont want to replace whole screen. I just want to replace the content of main_content with another widget.

I am not sure if it can be done using flutter package go_router. Or I have to use state management for this case.

I tried Go_router shell routes. But i think it is made for different purpose.

enter image description here


Solution

  • router config :

    final GlobalKey<NavigatorState> _shellNavigatorKey =
    GlobalKey<NavigatorState>(debugLabel: 'shell');
    
    const String pageOne = '/pageone';
    const String pageTwo = '/pagetwo';
    
    final appRouter = GoRouter(
      initialLocation: pageOne,
      routes: [
        ShellRoute(
          navigatorKey: _shellNavigatorKey,
          builder: (BuildContext context, GoRouterState state, Widget child) {
            return MainPage(child: child);
          },
          routes: [
            GoRoute(
              path: pageOne,
              builder: (BuildContext context, GoRouterState state) =>
                  const MainContent(lable: 'one'),
            ),
            GoRoute(
              path: pageTwo,
              builder: (BuildContext context, GoRouterState state) =>
                  const MainContent(lable: 'two'),
            ),
          ],
        )
      ],
    );
    

    main page class :

    class MainPage extends StatelessWidget {
      //child is the content of each page
      final Widget child;
      const MainPage({super.key, required this.child});
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          body: Row(
            children: [
              //SideBar
              Expanded(
                flex: 1,
                child: Container(
                  color: Colors.blue,
                  child: ListView(
                    children: [
                      GestureDetector(
                          onTap: () => context.go(pageOne),
                          child: const Text('page One')),
                      GestureDetector(
                          onTap: () => context.go(pageTwo),
                          child: const Text('page Two')),
                    ],
                  ),
                ),
              ),
              Expanded(
                  flex: 2,
                  child: Column(
                    children: [
                      //Header
                      Container(
                        width: double.infinity,
                        padding: const EdgeInsets.all(16),
                        color: Colors.red,
                        child: const Text('Header'),
                      ),
                      //main_MainContent
                      Expanded(child: child),
                    ],
                  )),
            ],
          ),
        );
      }
    }
    

    main content class :

        class MainContent extends StatelessWidget {
      final String lable;
      const MainContent({super.key, required this.lable});
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          body: Center(
            child: Text(lable),
          ),
        );
      }
    }
    

    run app :

        void main(List<String> args) {
      runApp(const MyApp());
    }
    
    class MyApp extends StatelessWidget {
      const MyApp({super.key});
    
      @override
      Widget build(BuildContext context) {
        return MaterialApp.router(
          routerConfig: appRouter,
        );
      }
    }
    

    resault :

    enter image description here