I have a problem with the structure of Flutter project.
At the moment structure looks like this:
Homepage with bottomNavigationBar with multiple tabs, each tab is StatefulWidget and contains some heavy processing (remote API calls and data display).
In case I call Navigator.pushNamed from inside of any tab, following happens:
- All tabs are being rebuild in the background (making API calls, etc).
- New page opens normally.
- When I press back button, page closes and all tabs are rebuild again.
So in total everything (each tab) is rebuilt 2 times just to open external navigator page.
Is this some sort of bug? Completely not understandable why it's fully rebuilding bottomNavigationBar just before pushing new route.
How it should work:
- When I call Navigator.pushNamed from inside the tab, new page should be open and all bottomNavigationBar tabs should not be rebuild and stay in unchanged state.
- When I press back, page should close and user return to the same state of bottomNavigationBar and it's tabs, no rebuilding at all.
Is this possible to achieve?
Here is the code:
class HomePage extends StatefulWidget {
@override
_HomePageState createState() => new _HomePageState();
}
class _HomePageState extends State<HomePage> {
int index = 0;
final _tab1 = new tab1(); //StatefulWidget, api calls, heavy data processing
final _tab2 = new tab2(); //StatefulWidget, api calls, heavy data processing
@override
Widget build(BuildContext context) {
debugPrint('homepage loaded:'+index.toString());
return new Scaffold(
body: new Stack(
children: <Widget>[
new Offstage(
offstage: index != 0,
child: new TickerMode(
enabled: index == 0,
child: _tab1,
),
),
new Offstage(
offstage: index != 1,
child: new TickerMode(
enabled: index == 1,
child: _tab2,
),
),
],
),
bottomNavigationBar: new BottomNavigationBar(
currentIndex: index,
type: BottomNavigationBarType.fixed,
onTap: (int index) { setState((){ this.index = index; }); },
items: <BottomNavigationBarItem>[
new BottomNavigationBarItem(
icon: new Icon(Icons.live_help),
title: new Text("Tab1"),
),
new BottomNavigationBarItem(
icon: new Icon(Icons.favorite_border),
title: new Text("Tab 2"),
),
],
),
);
}
}
Here is single tab code:
class tab1 extends StatefulWidget {
@override
tab1State createState() => new tab1State();
}
class tab1State extends State<tab1> {
@override
Widget build(BuildContext cntx) {
debugPrint('tab loaded'); //this gets called when Navigator.pushNamed called and when back button pressed
//some heave processing with http.get here...
//...
return new Center(
child: new RaisedButton(
onPressed: () {
Navigator.pushNamed(context, '/some_other_page');
},
child: new Text('Open new page'),
));
}
}