Handle your application routing, synchronize it with browser URL and more. Beamer
uses the power of Navigator 2.0 API and implements all the underlying logic for you.
Key Concepts
The key concept of Beamer is a BeamLocation
which represents a stack of one or more pages. You will be extending BeamLocation
to define your app’s locations to which you can then beam to using
Beamer.of(context).beamTo(MyLocation()) // or context.beamTo(MyLocation())
or beamTo
a specific configuration of some location;
context.beamTo( BooksLocation( pathBlueprint: '/books/:bookId', pathParameters: {'bookId': '2'}, ), ),
You can think of it as teleporting / beaming to another place in your app. Similar to Navigator.of(context).pushReplacementNamed('/my-route')
, but Beamer is not limited to a single page, nor to a push per se. You can create an arbitrary stack of pages that gets build when you beam there.
Using Beamer can feel like using many of Navigator
‘s push/pop
methods at once.
Note that “Navigator 1.0” can be used alongside Beamer. You can easily push
or pop
pages with Navigator.of(context)
, but those will not be contributing to the URI. This is often needed when some info/helper page needs to be shown that doesn’t influence the browser’s URL. And of course, when using Beamer on mobile, this is a non-issue as there is no URL.
Examples
Books
Here is a recreation of books example from this article where you can learn a lot about Navigator 2.0. See Example for full application code of this example.
Advanced Books
For a step further, we add more flows to demonstrate the power of Beamer. The full code is available here.
Deep Location
You can instantly beam to a location in your app that has many pages stacked (deep linking) and then pop them one by one or simply beamBack
to where you came from. The full code is available here.
Guards
You can define global guards (for example, authentication guard) or location guards that keep a specific location safe. The full code is available here.
Bottom Navigation (WIP)
An example of putting Beamer
into widget tree. This is not yet fully functional for web usage; setting the URL from browser doesn’t update the state properly. It should work when nested routers issue is done. The full code is available here.
Usage
With *App.router
In order to use Beamer on your entire app, you must (as per official documentation) construct your *App
widget with .router
constructor to which (along with all your regular *App
attributes) you provide
routerDelegate
that controls (re)building ofNavigator
pages androuteInformationParser
that decides which URI corresponds to whichRouter
state/configuration, in our case –BeamLocation
.
Here you use the Beamer implementation of those – BeamerRouterDelegate
and BeamerRouteInformationParser
, to which you pass your BeamLocation
s.
class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp.router( routerDelegate: BeamerRouterDelegate( initialLocation: HomeLocation(), ), routeInformationParser: BeamerRouteInformationParser( beamLocations: [ HomeLocation(), BooksLocation(), ], ), ... ); } }
As a Widget (WIP)
class MyApp extends StatefulWidget { @override _MyAppState createState() => _MyAppState(); } class _MyAppState extends State<MyApp> { final List<BeamLocation> _beamLocations = [ BooksLocation(pathBlueprint: '/books'), ArticlesLocation(pathBlueprint: '/articles'), ]; final _beamerKey = GlobalKey<BeamerState>(); Beamer _beamer; int _currentIndex = 0; @override void initState() { _beamer = Beamer( key: _beamerKey, routerDelegate: BeamerRouterDelegate(initialLocation: _beamLocations[0]), routeInformationParser: BeamerRouteInformationParser( beamLocations: _beamLocations, ), ); super.initState(); } @override Widget build(BuildContext context) { return MaterialApp( debugShowCheckedModeBanner: false, home: Scaffold( body: _beamer, bottomNavigationBar: BottomNavigationBar( currentIndex: _currentIndex, items: [ BottomNavigationBarItem(label: 'Books', icon: Icon(Icons.book)), BottomNavigationBarItem( label: 'Articles', icon: Icon(Icons.article)), ], onTap: (index) { setState(() => _currentIndex = index); _beamerKey.currentState.routerDelegate .beamTo(_beamLocations[index]); }), ), ); } }
General Notes
- When extending
BeamLocation
, two getters need to be implemented;pathBlueprints
andpages
.pages
represent a stack that will be built byNavigator
when you beam there, andpathBlueprints
is there for Beamer to decide whichBeamLocation
corresponds to an URL coming from browser.BeamLocation
takes query and path parameters from URI. The:
is necessary inpathBlueprints
if you might get path parameter from browser.
BeamPage
‘s child is an arbitraryWidgets
that represent your app screen / page.key
is important forNavigator
to optimize rebuilds. This should be an unique value for “page state”.BeamPage
createsMaterialPageRoute
, but you can extendsBeamPage
and overridecreateRoute
to make your own implementation instead.
Migrating from 0.4.x to >=0.5.x
- instead of wrapping
MaterialApp
withBeamer
, use*App.router()
String BeamLocation.pathBlueprint
is nowList<String> BeamLocation.pathBlueprints
BeamLocation.withParameters
constructor is removed and all parameters are handled with 1 constructor. See example if you needsuper
.BeamPage.page
is now calledBeamPage.child
Contributing
This package is still in early stages. To see the upcoming features, check the Issue board.
If you notice any bugs not present in issues, please file a new issue. If you are willing to fix or enhance things yourself, you are very welcome to make a pull request. Before making a pull request;
- if you wish to solve an existing issue, please let us know in issue comments first
- if you have another enhancement in mind, create an issue for it first so we can discuss your idea
Also, you can to speed up the development.
Download Flutter Route API Plugin source code on GitHub
https://github.com/slovnicki/beamer
Provides the list of the opensource Flutter apps collection with GitHub repository.