This article by Jian Yue SimpRead transcoding, original address medium.com
Running for almost a year on pub.dev, tested and used by many individuals and companies, long……
Beamer V1.0.0 has been released! What is new and how to migrate
After running on pub.dev for almost a year, and after testing and use by many individuals and companies, the long-awaited _v1.0.0_ has finally been released.
directory
- Introduction to the
- What’s new after V0.14.1
- How to transfer
- Final thoughts
Introduction to the
Beamer is an all-platform routing package that lets you navigate through protected page stacks and urls using Router and Navigator’s Pages API (aka “Navigator 2.0”).
Learning Flutter’s new Navigation and Routing System is a good article to start reading if you are not familiar with these navigation concepts. The rest of this article assumes familiarity with the above concepts and some familiarity with Beamer, whose README can be read at the link below.
Beamer | Flutter package
Handle routing of your application on all platforms, synchronizing it with the browser URL bar, and so on. The power Beamer uses is…
Pub. Dev/packages/be…
Two main ideas guided Beamer’s birth.
- Make the Router API easier to use, especially for beginners
- Separate the responsibility of creating a page stack for intermediate and advanced use.
The first is addressed through the default implementation of “RouterDelegate “and “RouteInformationParser”, namely “BeamerDelegate “and “BeamerParser”. Both can be customized by taking various parameters. Having named routes appears to be a desired feature from the start, so there is a RoutesLocationBuilder that can be configured with the familiar Routes map. Once set, navigation can be done by beaming.of (context).beamtonamed (‘/my/page/2’), This makes the transition from navigator.of (context).pushnamed (‘/my-page’) very natural for newcomers.
The second is accomplished by the concept of a BeamLocation, which is responsible for determining, based on its state, which pages the BeamerDelegate should put into navigator.pages when it (re) builds. The idea here is to define different BeamLocations for different “regions/places/worlds” in the application. For example, we could have BooksBeamLocation to handle all combinations of book-related pages in a stack, and ArticlesBeamLocation to handle all articles-related pages in a stack. The benefits of this approach quickly become apparent when you need to build an application with more than 10 screens organized into several “context-different” page stacks.
When defining your “BeamLocation “, the “state “used for it can be either the default “BeamState” (which holds various routing parameters important in deciding how to build a page stack) or a completely custom state object, Even (but not required) a “ChangeNotifier”. Pure declarative navigation can be achieved when a custom ChangeNotifier is used as the state of a BeamLocation. However, even with the ChangeNotifier state, people can perform mandatory navigation just as well. Mr Beamer does not favour one over the other; his treatment of both is similar. The next goal might be to make the default BeamState a ChangeNotifier, but that’s the subject of the next article 🙂
The flow that occurs after each navigation action can be seen in the figure below.
What’s new after V0.14.1
A full change log can be seen at pub.dev, so we’ll take a look at the reasons behind each breakthrough change and some points worth mentioning.
The change of BeamState
- It is with
RouteInformationSerializable
Blend, which is a blend element defined in Beamer, eachBeamLocation
Must be mixed with it. pathBlueprintSegments
renamedpathPatternSegments
.
The change of BeamerDelegate
- Some of you may have noticed, especially if used directly
Beamer.of(context).update
.BeamerDelegate
It also stores its “state”. Before that, this was a program calledThe state of '
BeamState’, but that doesn’t feel right. Now this is a “Configuration”RouteInformation
, andRouterDelegate
With the same name. - All beam parameters such as
transitionDelegate',
BeamBackOnPop ‘and others are extracted into a’ BeamParameters’ object. This is not a breakthrough change, as these parameters remain unchanged in the beam function, but it is a change that, along with the above changes, affects the following changes locationBuilder
Now acceptRouteInformation
andBeamParameters
Rather thanBeamState
. This is a natural consequence of the above changes, but also an improvement as it provides willBeam parameters
The ability to preserve history in a way that wasn’t possible before.beamStateHistory
andbeamLocationHistory
Be replaced bybeamingHistory
It’s aList<BeamLocation>
, eachBeamLocation
There arehistory
, it isList<HistoryElement>
, includingHistoryElement
holdRouteInformation
andBeamParameters
. That phrase quickly escalated, but now we have a very stable and well-structured beam history.listener
Has been renamed torouteListener
And added a new onebuildListener
. This way, we can listen for incoming routes (before build) and at build time (where we can also access the page).
The change of BeamLocation
- Due to the “BeamerDelegate “change, the constructor now requires optional” routing information “and “BeamParameters”.
- “State” of the “T” type must be mixed with “RouteInformationSerializable”, now in the extension “BeamLocation”, must specify a generic types for state, even use the default “BeamState”.
PathBlueprints' name
PathPatterns’, is oneList<Pattern>
.
Changes about SimpleLocationBuilder
- rename
RoutesLocationBuilder
. This is due toNavigator 2.0 API Usability ResearchThe discussion of the routes
The value of is now also acceptedObject? data
Parameters.
Changes on BeamPage
pageRouteBuilder
Be more versatilerouteBuilder
To be replaced.- We now have one
const
The constructor - Added a static one
RoutePop ', can be used instead of the default
PathSegmentPop ‘for’ onPopPage’.
The change of BeamGuard
pathBlueprints
renamedpathPatterns
.-
beamTo
andbeamToNamed
Now also receiveorigin
andtarget
They are the place to which they are transmitted and the place to which they are transmittedBeamLocation
(This is protected).
A supplement to the example
- Guard riverpod example
- Firebase core instance
- Firebase auth example
- ChangeNotifier Custom status example
How to transfer
Although there are many changes, migration is very straightforward. We will go through two migration schemes; When using SimpleLocationBuilder and using custom BeamLocation.
Simple locator generator
As we mentioned above, SimpleLocationBuilder was renamed RoutesLocationBuilder. This completes 50% of the migration, we just need to add the data parameter to routes, but let’s write some code.
We used to have something like this
final routerDelegate = BeamerDelegate(
locationBuilder: SimpleLocationBuilder(
routes: {
'/': (context, state) => MyWidget(),
'/another': (context, state) => MyAnotherWidget(),
},
),
// other properties...
);
Copy the code
After migration, we should have something like this
final routerDelegate = BeamerDelegate(
locationBuilder: RoutesLocationBuilder(
routes: {
'/': (context, state, data) => MyWidget(),
'/another': (context, state, data) => MyAnotherWidget(),
},
),
// other properties...
);
Copy the code
Custom BeamLocation
As mentioned, we have to ‘rename pathBlueprints to pathPatterns’ and put in a concrete state’ type when extending BeamLocation’.
In version 0.14.1, we can have
class BooksLocation extends BeamLocation {
@override
List<Pattern> get pathBlueprints => ['/'.'/books'];
@override
List<BeamPage> buildPages(BuildContext context, BeamState state) {
return [
BeamPage(
key: const ValueKey('home'),
child: const HomeScreen(),
),
if (state.uri.pathSegments.contains('books'))
BeamPage(
key: const ValueKey('books'),
child: constBooksScreen(), ), ]; }}Copy the code
Now we have
class BooksLocation extends BeamLocation<BeamState> {
@override
List<Pattern> get pathPatterns => ['/'.'/books'];
@override
List<BeamPage> buildPages(BuildContext context, BeamState state) {
return [
const BeamPage(
key: ValueKey('home'),
child: HomeScreen(),
),
if (state.uri.pathSegments.contains('books'))
const BeamPage(
key: ValueKey('books'), child: BooksScreen(), ), ]; }}Copy the code
Note that we can now use the BeamPage of the const constructor instead of using it on all attributes (if we develop with the prefer_const_constructors lint rule).
miscellaneous
Visit currentBeamLocation. State
Now, the state type cannot be inferred automatically (even if it is a default BeamState), so we need to cast it manually to be able to access the required properties of its type.
We could have done it before
final beamState = Beamer.of(context).currentBeamLocation.state;
final bookId = beamState.pathParameters['bookId'];
Copy the code
Now we have to
final beamState = Beamer.of(context).currentBeamLocation.state as BeamState;
final bookId = beamState.pathParameters['bookId'];
Copy the code
BeamGuard
For example, in BeamLocation, pathBlueprints are renamed pathPatterns, and beamTo/beamToNamed gets two parameters.
We used to have
BeamGuard(
pathBlueprints: ['/login'],
guardNonMatching: true,
check: (context, location) => context.isUserAuthenticated(),
beamToNamed: '/login'.)Copy the code
Now we have parameters like this
BeamGuard(
pathPatterns: ['/login'],
guardNonMatching: true,
check: (context, location) => context.isUserAuthenticated(),
beamToNamed: (origin, target) => '/login'.)Copy the code
Final thoughts
I hope this article will be helpful to anyone who is already using Beamer, or even to anyone who is considering starting a new navigation concept. It was definitely (and was) fun for me, and I plan to write more about it in the future.
Feel free to visit Beamer’s GitHub repository or Discord server to further discuss and understand any problems you may be encountering.
www.deepl.com translation