Reputation: 3593
The app I am developing attempts to adopt, as much as possible, the most native experience for Android & iOS users.
To do so, the app runs a CupertinoApp
and a MaterialApp
.
On iOS, I use the CupertinoScaffold
showing a CupertinoTabBar
with BottomNavigationBarItems
. It performs very well as expected:
on Android, the story is different: I am using the Drawer
widget.
When I click on an entry, I call Navigator#push
to show the associated page. However, this will keep adding new instances of each entry's page in the stack.
I don't seem to be able to return to an existing page. At least, not how I can do it with iOS.
Looking at the Navigator
I see functions that seem to achieve what I am looking for:
popUntil
=> will show my existing screen, but at the expanses of all the other ones that will therefore make a sacrifice for the sake of just one page. So much ado for nothing...pushReplacement
=> will show a new instance of the target page and destroy the current one. Not desirable.What am I missing ? How can I achieve that the CupertinoTabBar
seems to be able to do?
Upvotes: 0
Views: 956
Reputation: 3593
Well, I solved my issue by taking another direction.
Simply put I don't think there is a way, with the Navigator
to achieve what I want.
The solution I find out was: Keep state of widgets with Bottom Navigation Bar in Flutter
This guide suggests to use a IndexedStack
that displays only one child at the time while keeping its state.
So this is how I managed to make it work:
MaterialApp
home
to be a custom stateful widget called MaterialHomePage
MaterialHomePage
builds a Scaffold
:
AppBar
and its title (the title of the active page);drawer
and its arguments (more on that later)body
is that so-called wonderful IndexedStack
:
children
to be the list of pages / widgets, the same pages available in the drawerindex
to be the property _selectedPageIndex
of your MaterialHomePage
setState
occurs inside of which you may update the _selectedPageIndex
property as well as _selectedPageIndex
property`.Drawer
:
Function
with the target page title & indexListTile
) as pages you have declared in the IndexedStack
displayed in MaterialHomePage
.At the end, what happens:
MaterialHomePage
gets notified (via callback) of the user choice which triggers a setStage
that will both:
IndexedStack
with index = 3
AppBar
's titleand voilà there you go: each page gets retained, no loss of state and a smooth navigation.
NB: if the user uses the Android's back button feature, at this point it will close the app since the Navigator
stack is empty. Maybe there is a way to listen for such an event if you desire to default to the first entry / page (displayed at launch) if the user was in a another page.
NB2: I also wonder if there is a way to animate page transitions.
PS: Let me know if the answers is a fine solution in which case I'll validate it. Or if you find a proper way to achieve it.
Upvotes: 0