Open rydmike opened 3 years ago
Hi @tomgilder I edited the above long Flexfold demo based case study, that contains all the use cases I have been unable to solve with Routemaster.
The issues are still the same as day 1 when I first tried to use Routemaster for my custom Flexfold scaffold (which is based on SDK Scaffold) and get it to navigate as desired. Perhaps I'm trying to get Routmaster to do things it cannot or perhaps I'm going about it the wrong way.
The explanations above are a bit long, not difficult, just verbose. Here is another way to describe it all, based on a fictive setup with Flutter SDK widgets.
Scaffold
used as a "home" page for root "/". NavigatioRail
are used to describe top level routes, they also have "/page" style named routes.BottomNavigationBar
, but some that do not fit (max 5 can fit) are defined to not be shown in the bottom navigation bar, they will only show up in a Drawer (without bottom destination) or Rail/Sidemenu that also contains the bottom destinations.If the app is on a tablet, web or desktop and wide enough, then we get into rail/menu territory.
If we are changing to this view via a responsive layout change on web/desktop, the state of all pages from phone sized view are kept, and I mean all, nested stacked ones and whatever. The view changes with animation, bottom navbar slides away (down), rail or side menu slides in from left or right (if RTL). Pages keep their state, the shown current one, but also all the other destinations that we might have visited already via the bottom navigation bar.
That pages keep the state when transitioning between the responsive views is a requirement. So we must keep them all in a PageSwitchingView
like construct, that I borrowed from the CupertinoTabScaffold
. But we must show pages from its index based view storage, with different transitions and even different Navigators, depending on what responsive layout view we are in.
I have a semi working setup with Nav1 using nested navs for al this, but I need Nav2 for the URL crap, URL entry navigation, back button(s), deep links, URL query parameters and all this web crap as well, hehe.
I have not really tried getting into trying to build it from scratch using Nav2, I have been hoping that some package like yours would come along and spare me from the trouble.
Almost there, but not quite... π
Like I said, perhaps I'm going about it the wrong way when trying to use Routemaster for it, or maybe it is not possible to use it for it, not sure yet.
I should probably setup a "simple" (well it cannot really be super simple, but simpler than Flexfold anyway) example based on the above description using SDK widgets, because, if that example can be solved, then so can my Flexfold setup.
Hi @tomgilder, I'm really enjoying exploring Routemaster. So impressed by it!
While trying to use Routemaster on the demo application for my still unpublished and not yet fully ready Flexfold adaptive and responsive scaffold package (info here https://rydmike.com/) and live older version of the the demo app here https://rydmike.com/demoflexfold.
I ran into some use case issues or maybe more like questions. However, in order to present them I first need to explain a bit what Flexfold is and how it works.
Flexfold info
Flexfold works a lot like the Navigation Rail in Flutter SDK, but it handles also bottom navigation bar, drawer, rail and side menu, plus a sidebar. And it has a lot of design features and behavior parameters. Also when using Flexfold on variable size canvas, the transition between the layouts for the different navigation types are animated, it just looks cooler than a sudden jump to the new responsive layout view.
The setup of navigation destinations is similar to the Navigation Rail, you just define a bunch of destinations, with labels, icons, tooltips and also path based named routes if you like. Then you give this as config data to Flexfold. When you click on destinations in the Flexfold scaffold it just returns via a callback what the destination was. You handle the actual routing yourself, so it is totally agnostic to what kind of routing you use, as it should be.
Flexfold Destinations
With Flexfold you just define destinations very much like for the navigation rail, but it has a few more options. For the the live demo app it looks like this:
This will when used with the the Flexfold scaffold result in scaffold that looks like below in the main different responsive use cases:
Flexfold phone size view
Flexfold tab size view
Flexfold desktop size view with side bar
Flexfold destination info.
In the demo app you can see the type of info it returns based on what mode was used to go to a new destination:
You get an overall menu index, bottom index and the named path route you defined for the destinations. Plus an enum indicating what was used: bottom, drawer, rail, menu, plus direction reverse: false/true (moving to lower or higher index), both these are intended to be used as info for a way to vary the transition based on where user clicked to go to the destination. The reverse info can be used to have a slight left/right type of slide on bottom bar or up/down on rail/menu, if so desired.
What you do and how you navigate based on the 'onDestination' info is up to whatever used navigation implementation.
Challenges with Routemaster and Flexfold demo app
I had on purpose left out all fancy Web based URL navigation from the Flexfold web demo. Simply because I had no simple and quick way of doing it. I now wanted to try and see if I can solve it it with your wonderful Routemaster package.
Mostly I think I can, and if I can't it is perhaps just because I'm not yet 100% familiar with all its possibilities. It certainly has much more features than I need when it comes to web routing, at least in this simple demo. I might even add some more features to the demo later to show off some more capabilities that your router solves beautifully.
Here are some of the challenges and question I have stumbled on so far:
A) General State Storing Navigator - partially solved - but web URL entry does not navigate
In the demo (and another more real use case too) I want to store and keep the state of all the destinations that are available as direct "top" destinations in the Flexfold scaffold.
The
CupertinoTabScaffold
,CupertinoTabBar
,CupertinoTabPage
and theStackNavigator
setup, like you do in the mobile_app demo is a great way of doing this. But of course we cannot use aCupertinoTabScaffold
in this use case, and we also have noCupertinoTabBar
, (even if one might be baked into the Flexfold scaffold, if that is used as bottom UI widget), when using theFlexfold
scaffold.For the Flexfold demo app, using the above shown destinations, I made this simple test setup to try routemaster:
and for
buildRouteMap
this worked well enough for the simple demo app:As an experiment I used
CupertinoTabPage
as my root route. The childLayoutShellWrapper
is a Widget the has the Flexfold scaffold in it, so noCupertinoTabScaffold
. For the body it just uses a variant of what theCupertinoTabScaffold
uses internally to keep the pages in memory off stage when so needed. For this I just copied the implementation detail, namely the_TabSwitchingView
and made aPageSwitchingView
version of it. It is identical to it, only public and some props renamed a bit.With it, in the Flexfold scaffold's build I can still do:
In its
onDestination
we can just set:The
Flexfold
has abody
property like a Material scaffold, so we can then do this in its body:This all actually works beautifully and state is kept when navigating between all "top" destinations in the Flexfold scaffold and they all have their own stack as well.
I noticed that in the
onDestination
I can instead of setting the controller index, also navigate to the page with the returned path by doing a:This is nice because it means it will easily even support my "modules" need for Flexfold destinations.
This is just a simple idea where destinations could also have module ID and you can swap out shown destinations in Flexfold by selecting the module. The modules can of course share some routes, like home, help, about etc... if so desired.
This just means that this setup could be used to always navigate to the right page based on the returned path from the destination and just ignore the indexes. The indexes are just used to hold and store all the pages in the for the keeping state when navigating to different destinations even between modules. This consumes more ram for sure, but for my particular use case it is what is needed on desktop and web. No idea how well it will perform yet. If it becomes to memory hungry I can also go back to the idea that only navigation within a module keeps state. The app implementation would just keep which index was last used in each module, so you are at least back on same page where you where when switched to another module. But if it performs OK while keeping state of all pages, that is even nicer UX wise.
This all seemed to work very well, but...
Except, this setup seem like it has no hooks into handling the URL entry from the browser (or back button). The browser URL updates when navigating from the UI fine, but because I'm not using a
CupertinoTabScaffold
I am of course not getting all the nice browser URL entry based navigation you baked into routemaster when usingCupertinoTabScaffold
. I have not yet figured out how I can get it to also update it based on browser URL entry when using routemaster and myPageSwitchingView
.It now keeps the state of top destinations, like I want it to, and also the tabs. The tab sub views on the tabs destination is just a normal routemaster tab page view, the sub pages for the tabs page are not part of the Flexfold destination, only the tab page is, so for that those pages the URL entry based update of the tabs, and browser back, even works OK.
Here is a slowish debug build (with low GIF framerate o make it small so it fits on GH) showing the Flexfold demo using routemaster with the URL updating OK when navigating, with state of all main destinations kept, and URL based navigation entry even working on the tabs page too.
However on the main destinations the URL entry does not work, since there is no built-in support for it. I wonder if there is some hook I could tie into in order to add it? Or if this is a case where support for something like the PageSwitchingView() in routemaster is needed?
B) A Tab or Cupertino Page content as a full page pushed on top of root.
The other case I'm wondering about. How I can when the
onDestination
returneddestination
hasdestination.useModal
set totrue
, how can I then instead of using thePageSwitchingView
view in the body, instead push it as new screen on top of the entireLayoutShellWrapper
while using (showing) the same route path as it has in the wrapper view? A need to wrap the content in a Scaffold with an AppBar might be there, although in the live demo in its nested nav1 I could actually even avoid that. With nav 1, I just used another navigator, well the root one and not the one nested into the body of Flexfold, and pushed it on top of the stack with that covering the Flexfold wrapper and its "body" nested navigator.EDIT (28.5.2021): Tried a bunch of things, but nothing really produces the correct result.
I feel to do this I must have access to a lower root navigator, than the first IndexedPage tied to root "/" route with its PageStackNavigator to be able to push a page on top of it. Also when I trigger that one, I need to prevent the navigator tied to the root "/" from navigating, ie showing the same page inside the scaffold that it normally wants to do in another layout scenario, instead in this scenario I want to push the page on top of everything and the page stack below must remain where it is, so when the page pushed on top of it is popped, it remains where it was. Hmm... I will experiment more I guess. Feel a bit stuck though.
C) Transition selection
Based on the examples and docs, it does seems like I should be able to grab the Flexfold
destination.source
(drawer, bottom, rail, menu) and pass it along to a page transition builder, so that when navigation happens I can switch there for the different desired transition styles, just like I'm doing in the live version of demo app with navigator 1 already.EDIT (28.5.2021): I tried two different setups with the config described in A) and B) above, but I cannot get any page transitions with it regardless what I try.
Maybe it is custom
PageSwitchingView
that kills them, it contains some no off stages transition thing. If that is it, I should see the same issue withCupertinoTabScaffold
that uses it as well, I will check that out.Sorry this was a super long questions posts, but I like to put things in context so the use case and scenarios can be properly understood. Not sure I managed to do so, I tend to be so darn verbose, hehe π
So far I think routemaster rocks πͺπ» π , and if I can get the above cases to work, I have no reason to build anything from scratch with Nav2 for any use case.