skip to Main Content

I need to do navigation using GlobalKey. Previously it worked, but after I add builder in the MaterialApp, now my navigation no longer works.

Here is my example code to reproduce the issue.

GlobalKey<NavigatorState> navigatorKey = GlobalKey<NavigatorState>();

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      navigatorKey: navigatorKey,
      home: HomePage(),
      theme: ThemeData(
        primaryColor: Color(0xffff5e57),
        colorScheme: ColorScheme.light(secondary: Color(0xffff3f34)),
      ),
      routes: {
        '/second_page': (context) => SecondPage(),
      },
      builder: (BuildContext context, Widget? child) {
        return HomePage();
      },
    );
  }
}

class SecondPage extends StatelessWidget {
  const SecondPage({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(),
    );
  }
}

class HomePage extends StatelessWidget {
  const HomePage({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Example'),
      ),
      body: Container(
        width: double.infinity,
        height: double.infinity,
        padding: EdgeInsets.all(16),
        child: Center(
          child: ElevatedButton(
            child: Text("Open New Page"),
            onPressed: _openNewPage,
          ),
        ),
      ),
    );
  }

  void _openNewPage() {
    navigatorKey.currentState?.pushNamed('/second_page');
  }
}

How do I fix it? I still need a navigation using GlobalKey also with builder in the MaterialApp.

2

Answers


  1. In this code, I’ve removed the builder property and used the onGenerateRoute property to define the routes. The Navigator.of(context) is used to push the route when the button is pressed in the HomePage. This will make your navigation work as expected.

    Follow the code:

    import 'package:flutter/material.dart';
    
    void main() {
      runApp(MyApp());
    }
    
    class MyApp extends StatelessWidget {
      final GlobalKey<NavigatorState> navigatorKey = GlobalKey<NavigatorState>();
    
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          navigatorKey: navigatorKey,
          theme: ThemeData(
            primaryColor: Color(0xffff5e57),
            colorScheme: ColorScheme.light(secondary: Color(0xffff3f34)),
          ),
          home: Builder(
            builder: (context) {
              // Wrap the output of builder with a Navigator widget
              return Navigator(
                key: navigatorKey,
                onGenerateRoute: (settings) {
                  switch (settings.name) {
                    case '/':
                      return MaterialPageRoute(builder: (context) => HomePage());
                    case '/second_page':
                      return MaterialPageRoute(builder: (context) => SecondPage());
                    default:
                      return null;
                  }
                },
              );
            },
          ),
        );
      }
    }
    
    class SecondPage extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(),
        );
      }
    }
    
    class HomePage extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: Text('Example'),
          ),
          body: Container(
            width: double.infinity,
            height: double.infinity,
            padding: EdgeInsets.all(16),
            child: Center(
              child: ElevatedButton(
                child: Text('Open New Page'),
                onPressed: () {
                  // Use the GlobalKey to navigate
                  navigatorKey.currentState?.pushNamed('/second_page');
                },
              ),
            ),
          ),
        );
      }
    }
    
    
    
    Login or Signup to reply.
  2. To fix the issue and keep the navigation working, you should modify the builder to wrap the provided child widget instead of returning a new HomePage(). Here’s the code:

     return MaterialApp(
       navigatorKey: navigatorKey,
       home: HomePage(),
       theme: ThemeData(
        primaryColor: Color(0xffff5e57),
        colorScheme: ColorScheme.light(secondary: Color(0xffff3f34)),
      ),
        routes: {
        '/second_page': (context) => SecondPage(),
      },
        builder: (BuildContext context, Widget? child) {
        return child!;
      },);
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search