csells / go_router

The purpose of the go_router for Flutter is to use declarative routes to reduce complexity, regardless of the platform you're targeting (mobile, web, desktop), handling deep linking from Android, iOS and the web while still allowing an easy-to-use developer experience.
https://gorouter.dev
441 stars 97 forks source link

provide for multiple navigation stacks? #82

Closed csells closed 2 years ago

csells commented 3 years ago

e.g. https://medium.com/coding-with-flutter/flutter-case-study-multiple-navigators-with-bottomnavigationbar-90eb6caa6dbf

csells commented 2 years ago

The scenario that I get asked about all the time is for a tabbed ui (whether on the top or the bottom) to have a nav stack per tab and that switching between tabs should remember the users spot in the nav stack for each tab. I've come to understand that this is what "nested nav" means to people and it's a common app requirement that go_router should support.

II11II commented 2 years ago

I've created a small demo of a persistent bottom navigation with independent routes and helper methods to navigate across different tabs (similar to how the Play Store Console behaves with its Navigation Rail).

I don't know how feasible would be for go_router to implement something like this out of the box. This approach uses IndexedStack which persists the different children states in memory.

https://github.com/davidmartos96/go_router_bottom_nav_demo/tree/main/lib

Hi @davidmartos96 Thank you for good idea, but app loses deep link functionality

image
davidmartos96 commented 2 years ago

I've created a small demo of a persistent bottom navigation with independent routes and helper methods to navigate across different tabs (similar to how the Play Store Console behaves with its Navigation Rail).

I don't know how feasible would be for go_router to implement something like this out of the box. This approach uses IndexedStack which persists the different children states in memory.

https://github.com/davidmartos96/go_router_bottom_nav_demo/tree/main/lib

Hi @davidmartos96 Thank you for good idea, but app loses deep link functionality

image

Yes, unfortunately that approach doesn't quite work for web deep linking.

esDotDev commented 2 years ago

The problem is that once the user taps the "recents" tab in the BottomNavigationBar, the previous route might have been /song/1, and there's no obvious way to use go_router to store this state, but I'm not sure if it should.

Right, this is one of the core pieces of logic provided by lulu's tabbed router example. Someone needs to remember what was the last visited url for each tab, so that when the tab is clicked, it can link into the last loaded url for that tab (or fallback to the "home tab")

The simplest way I've done this in the past, is to just addListener onto GR, and save a list of url changes. Then when a tab is pressed, (eg "settings") it can just check that history and grab the last url that .startsWith('/settings') and this works pretty nicely with only a few lines of code.

This is an alternative to actually having real nested navigators, each with their own stack of pages. I'm not sure how that would actually work when using names routes... this approach is more about faking it so it gives the appearance or general UX of individual navigators.

mark8044 commented 2 years ago

Thanks for everyone work on this issue. Solving this would make go_router the router to use.

One issue with other implementations of BottomNavigation and IndexedStacks is that on iOS you lose access to the scroll-to-top with status bar tap functionality. This is because of issues with the PrimaryScrollController from a root stack eating up those clicks. And if you try to pass PSC to all the different stacks then they all scroll up.

So far using CupertinoTabScaffold/CupertinoTabBar doesn't seem to carry the problem (but has so many other problems with routers).

Just throwing this out there as something to keep in mind with your implementations. If its working with your implementation, then mores the better!

On the edge of my app to see if this comes to go_router as everything else seems to work really well and easy

techouse commented 2 years ago

@mark8044 Yeah, I've faced the same issue and just done what Facebook does in their app. A repeated tap on the currently active bottom nav takes you back to the top 🤷

davidmartos96 commented 2 years ago

Thanks for everyone work on this issue. Solving this would make go_router the router to use.

One issue with other implementations of BottomNavigation and IndexedStacks is that on iOS you lose access to the scroll-to-top with status bar tap functionality. This is because of issues with the PrimaryScrollController from a root stack eating up those clicks. And if you try to pass PSC to all the different stacks then they all scroll up.

So far using CupertinoTabScaffold/CupertinoTabBar doesn't seem to carry the problem (but has so many other problems with routers).

Just throwing this out there as something to keep in mind with your implementations. If its working with your implementation, then mores the better!

On the edge of my app to see if this comes to go_router as everything else seems to work really well and easy

I haven't tried, but couldn't you wrap every tab with a PrimaryScrollController widget and pass a different controller to each tab?

mark8044 commented 2 years ago

Thanks for everyone work on this issue. Solving this would make go_router the router to use. One issue with other implementations of BottomNavigation and IndexedStacks is that on iOS you lose access to the scroll-to-top with status bar tap functionality. This is because of issues with the PrimaryScrollController from a root stack eating up those clicks. And if you try to pass PSC to all the different stacks then they all scroll up. So far using CupertinoTabScaffold/CupertinoTabBar doesn't seem to carry the problem (but has so many other problems with routers). Just throwing this out there as something to keep in mind with your implementations. If its working with your implementation, then mores the better! On the edge of my app to see if this comes to go_router as everything else seems to work really well and easy

I haven't tried, but couldn't you wrap every tab with a PrimaryScrollController widget and pass a different controller to each tab?

I think the solution lies within that idea.

The problem so far with bottom nav implementations is you have a structure like this:

- Scaffold / PSC 
    - BottomNavigation -- Stack
          - Scaffold / PSC
               - Your page

So the BottomNav implementation uses as IndexStack that lies on top of a Scaffold and the clicks just don't pass to where you want them to.

Quite a few people have brought this up with flutter team, with ideas to allow us to access the root PSC, but that too is imperfect. Ive manually accessed the PSC before setting up a BottomNavigationBar and then passed it into the various tabs, and then the scroll to top does work, but then the problem is every list in every tab simultaneous scroll up, so that is also useless.

Whats interesting is things like WebView and InAppWebView work perfectly no mater where you put them in the tree, so I believe they are doing something along the lines of what you have mentioned. And of course CupertinoTabScaffold/CupertinoTabBar doesn't have this issue

wwwdata commented 2 years ago

Thanks for everyone work on this issue. Solving this would make go_router the router to use.

One issue with other implementations of BottomNavigation and IndexedStacks is that on iOS you lose access to the scroll-to-top with status bar tap functionality. This is because of issues with the PrimaryScrollController from a root stack eating up those clicks. And if you try to pass PSC to all the different stacks then they all scroll up.

So far using CupertinoTabScaffold/CupertinoTabBar doesn't seem to carry the problem (but has so many other problems with routers).

Just throwing this out there as something to keep in mind with your implementations. If its working with your implementation, then mores the better!

On the edge of my app to see if this comes to go_router as everything else seems to work really well and easy

I could easily solve the scroll to top problem by using the following package: https://pub.dev/packages/scrolls_to_top

Tananga commented 2 years ago

@csells We need something like this: https://youtu.be/9oH42_Axr3Q.