When it comes to navigation between multiple pages, you can’t get around the Flutter Navigator. However, repetitive code when calling the same pages over and over can be very annoying. Why not move page routing to a separate class and make routing even easier:

Check out the whole series on medium (and support my work):

content

The Basics

In order to jump to another page for example by clicking on a button we use the Flutter navigator:

TextButton(
  onPressed: () {
    Navigator.of(context).push(
      MaterialPageRoute(
        builder: (context) => Page2()
      )
    );
  },
  child: Text('Navigate to Page 2'),
),

Navigator.of(context) uses the Navigator instance with the current BuildContext . Then a new page is placed on top of the current one using the push function. In this, a new MaterialPageRoute is created, which references the new page in its build function.

Alternative functions on Navigator.of(context) are…

.pop() to return to the previous page

.popUntil((route) => condition) -> to navigate back to the previous page until the desired site appears

.pushReplacement(newRoute) -> to replace a page with the current one

.popAndPushNamed(routeName) -> similar to the previous one, but before that the navigation to the page is made uniquely identifiable with a string

.pushNamed(routeName) -> similar to the previous one, but without replacing the current page with it

Now imagine you want to call not only a new page, but also pass values to it or transfer to an error page (404) in case of wrong navigation? The code becomes confusing and hard to read very quickly!

To solve this problem generate a class to handle dynamic routes.

The RouteGenerator

To realize the routing via a separate class, 3 things have to be done:

1. create a class RouteGenerator

class RouteGenerator {
  static Route<dynamic> generateRoute(RouteSettings settings) {
    
    switch (settings.name) {
      case '/page1':
        return MaterialPageRoute(builder: (_) => Page1());
      case '/page2':
        return MaterialPageRoute(builder: (_) => Page2());
    }
  }

This class contains a static function which gets passed a RouteSettings object and returns a dynamic route. The name attribute of the passed object is used to locate the page to navigate and return the corresponding object.

2. assign the RouteGenerator in the main class

For this, the two attributes onGenerateRoute and initialRoute must be set.

class MyApp extends StatelessWidget {
  Widget build(BuildContext context) {

    return MaterialApp(
      onGenerateRoute: RouteGenerator.generateRoute,
      initialRoute: '/page1',
    );
  }
}

3. perform the navigation

Now a new page can be called using a simplified call similar to the one at the beginning. In this case, only a string identifier for the new page has to be passed:

TextButton(
  onPressed: () {
    Navigator.of(context).pushNamed('/page2');
  },
  child: Text('Navigate to Page 2'),
),

And that’s all to start with!

Follow me to not miss the following posts of this series


You may also like:

This post is also available on DEV.