11

Using Flutter’s Navigator 2.0 with Voyager | Flutter Community

 3 years ago
source link: https://medium.com/flutter-community/using-flutters-navigator-2-0-with-voyager-router-66728fc4e56b
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
Image for post
Image for post

Learn how to use Voyager library and Navigator 2.0 API together. Benefit from Flutter’s new features like browser history and declarative navigation without the need for all the boilerplate code.

The Problem: Navigator 2.0 Complexity

The new Navigator API is a fairly recent addition to Flutter. If you haven’t heard about it before I highly recommend checking this article by John Ryan: Learning Flutter’s new navigation and routing system.

Image for post
Image for post
Navigator 2.0 API overview

Needless to state the above looks complex. There is even an issue to make it simpler. You might quickly get overwhelmed by all the boilerplate code you need to put in first. While the new API is definitely powerful, getting everything right is a challenge.

If you just use Navigator and pages, the API is quite straightforward and declarative. Just state your pages and behold.

Unfortunately, as soon as you try using MaterialApp.router things get more complicated. You need to create RouterDelegate and RouteInformationParser. Your pages get encapsulated inside what one would call a controller. This is no longer declarative approach. You end up with an API similar to Navigator 1.0.

The Solution: Keep It Declarative, Simple.

Voyager builds on top of this new API and tries to make developer experience nicer.

Here’s how we could use Voyager with the plain Navigator.

Image for post
Image for post
Navigator.pages + VoyagerStack

As a precondition, we need to have Voyager’s router loaded (more info here). Once that is done, you can use the router instance with a VoyagerStack. The stack’s method asPages returns List<Page<dynamic>> instance that the Navigator is expecting.

If you plan to use the stack with the MaterialApp, you don’t need to worry about instigating the delegate and the information parser — just use VoyagerStackApp instead:

Image for post
Image for post
MaterialApp — Declarative Way

Put your MaterialApp within a createApp builder and handle system events from callbacks as you see fit. No need to worry about the delegate and your navigation stays declarative.

Nonetheless, if you prefer the imperative approach, you have an option to use VoyagerInformationParser and VoyagerDelegate directly:

Image for post
Image for post
MaterialApp — Imperative Way

Page Arguments and Scopes

The VoyagerStack can contain not only pages but also other stacks. Pages can take arguments, stacks can take scopes.

Image for post
Image for post
Example onboarding flow

In the above snippet, we’re providing a Bloc instance across multiple pages at once. This can be helpful when building complex flows that need to share common state.

Stack Serialization

You might not need stack serialization. This is only needed if you want to support browser history and have custom types in your stack (e.g. Bloc used as a scope). Since Flutter has no reflection, we need to register non-standard types manually — in our case it’s the LoginBloc:

Image for post
Image for post
Registration of non-standard types

Under the hood the VoyagerInformationParser will use registered adapters to persist the stack.

Stack Manipulation

The stack object is immutable. If you wish to modify the stack contents, you need to use mutate method:

Image for post
Image for post

This method gives you a copy of the underlying array which you can modify. For convenience, the stack comes with predefined removeLast method:

Image for post
Image for post

Unlike List.removeLast, this method removes nested stacks recursively. Additionally the scope element can implement VoyagerScopeRemovable — using VoyagerStack.removeLast can trigger resources disposal automatically.

Page Animations

By default all stack pages are wrapped with a MaterialPage when you call asPages method. If needed, you can provide your own wrapper using defaultPageBuilder parameter:

Image for post
Image for post

For finer control, you can register PagePlugin. This will make page wrapping a part of your navigation schema, customizable per each destination. Say we wanted to animate login screen from the bottom, this is what it could look like:

Image for post
Image for post
Voyager’s Navigation Map

Learn More

Check all the implementation details in the project’s example app. If you wish to try out Voyager with latest Navigator 2.0 API, you’ll need a 3.x version (a nullsafety prerelease):

Want to more about Voyager? Check the talk I gave during Droidcon SF 2019 — it’s a bit outdated now but it still contains relevant information about the core architecture.

Finally, don’t forget to check the project on GitHub — leave a ⭐, create an issue if you find a problem or open a PR. Thank you for your reading time 💖

🔗 Follow Flutter Community on Twitter: https://www.twitter.com/FlutterComm


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK