DEV Community

Cover image for Navigator overview in Flutter.
Samuel Wahome
Samuel Wahome

Posted on

Navigator overview in Flutter.

If you come from a native Android development background, then you've probably used Jetpack Navigation to navigate between Fragments in an application. The same can be said for UINavigationController if you come from an iOS background, which defines a stack-based scheme for navigating hierarchical content.

In Flutter, it is accustomed for one to use a Navigator widget to manage your screens or pages(which may also be referred to as routes). A stack is a data structure that manages pages. You insert the elements last-in, first-out, and only the element at the top of the stack is visible to the user.

There are currently two iterations of Navigation in Flutter: Navigator 1.0 and Navigator 2.0. Before we delve into Navigator 2.0, let's have a quick overview of Navigator 1.0.

GIF

Overview of Navigator 1.0

Navigator 1.0 provides a simple set of APIs for you to navigate between screens. The most common ones include:

  • push(): Adds a new route on the stack.
  • pop(): Removes a route from the stack.

One is able to add Navigator to a Flutter application via the use of WidgetsApp, which wraps many other common widgets that a Flutter app requires. Among these wrapped widgets is a top-level Navigator to manage the pages you push and pop. To get a deeper understanding of how navigation with named routes works, then this article will be of much help.

Using Navigator 1.0 may seem easy enough, but it does have its own disadvantages, which are:

  • There's no good way to manage your pages without keeping a mental map of where you push and pop a screen.
  • Navigator 1.0 doesn't expose the route stack to developers.
  • Navigator 1.0 does not update the web URL path.
  • On Android devices, the Back button might not work with Navigator 1.0 when you have nested navigators or when you add Flutter to your host Android app.

Overview of Navigator 2.0

Navigator 2.0 came with Flutter 1.22, which allowed one to take full control of the application's navigation stack. The main goals of this declarative API include but are not limited to:

  • Manage nested navigators: Gives you control over which navigator has priority.
  • Manage navigation state: This lets you parse routes and handle web URLs and deep linking.
  • Exposing the navigator's page stack: One can now manage app pages. 
  • Backward-compatible with imperative API: One can use both imperative and declarative styles in the same app.
  • Handle operating system events: Works better with events like the Android system's Back button.

https://medium.com/flutter/learning-flutters-new-navigation-and-routing-system-7c9068155ade

The above image shows an overview of Navigator 2.0's declarative API. The declarative API includes the following key components:

  • Page: An abstract class that describes the configuration for a route.
  • Router: Handles configuring the list of pages the Navigator displays.
  • RouterDelegate: defines how the router listens for changes to the app state to rebuild the navigator's configuration.
  • RouteInformationProvider: Provides RouteInformation to the router.
  • RouteInformationParser: Parses route information into a user-defined data type.
  • BackButtonDispatcher: Reports presses on the platform system's Back button to the router.
  • TransitionDelegate: Decides how pages transition into and out of the screen.

It is important to note, however, that this post is by no means a nudge towards using a particular navigation option, but only an overview of the two options that are available thus far, hence if you are happy with how the Navigator works today, you may keep using it in the same (imperative) way. If you do need any more information on the differences between the two approaches, then this video should be of much help:

Navigator 2.0 libraries to check out.

Navigator 2.0 may not be the easiest API to use out there, hence the following are some of the packages out there that wrap around the Navigator 2.0 API to make routing and navigation easier:

1. Beamer.

According to the official documentation:

Beamer handles your application routing on all platforms, synchronize it with the browser's URL bar, and more. Beamer uses the power of Router and implements all the underlying logic for you.

Beamer was designed to solve the following two major pain points:

  • Make the use of Router API easier, especially for beginners.
  • Segregate the responsibility of creating a page stack, for intermediate and advanced usage.

At the highest level, Beamer is a wrapper for Router and uses its own implementations for RouterDelegate and RouteInformationParser(BeamerDelegate and BeamerParser). The goal of Beamer is to separate the responsibility of building a page stack for Navigator.pages into multiple classes with different states, instead of one global state for all page stacks.

Beamer

2. go_router.

According to the official documentation:

go_router is a declarative router for Flutter based on Navigation 2 supporting deep linking, data-driven routes and more.

The goal of the go_router package is to simplify the use of the Router in Flutter as specified by the MaterialApp.router constructor. By default, it requires an implementation of the RouterDelegate and RouteInformationParser classes. These two implementations themselves imply the definition of a custom type to hold the app state that drives the creation of the Navigator.

3. flow_builder.

According to the official documentation:

flow_builder is a Flutter package which simplifies flows with a flexible, declarative API.

FlowBuilder is a widget that builds a navigation stack in response to changes in the flow state. onGeneratePages will be invoked for each state change and must return the new navigation stack as a list of pages.

FlowBuilder<Profile>(
  state: const Profile(),
  onGeneratePages: (profile, pages) {
    return [
      MaterialPage(child: NameForm()),
      if (profile.name != null) MaterialPage(child: AgeForm()),
    ];
  },
);
Enter fullscreen mode Exit fullscreen mode

4. fluro.

According to the official documentation:

Fluro is a null-safe Flutter routing library that adds flexible routing options like wildcards, named parameters, and clear route definitions.

Fluro prides itself on having the following features:

  • Simple route navigation
  • Function handlers (map to a function instead of a route)
  • Wildcard parameter matching
  • Querystring parameter parsing
  • Common transitions built-in
  • Simple custom transition creation
  • Follows beta Flutter channel

While that is a list of package options, they are by no means the only options out there, and thus the choice solely depends on your particular use case.

References.


That was indeed all that I have to share for now. To all readers, cheers to code🥂, and have a blessed day.

Discussion (0)