There is most certainly a way to organize this across different files. In addition to being easier to maintain and test, this may also increase performance if state is involved (because if state changes you have to rebuild the entire tree rather than only rebuilding leaf nodes).
However, this also means that if you have state involved and sprinkled about in your one large build()
method then you may have some additional considerations as you organize across files. This is assuming you would create new custom widgets to wrap the various components and you would need to orchestrate the state appropriately.
So with the goal of breaking this build method into different sub Widgets, I recommend you start by breaking it up into functions first:
from:
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
bottom: new TabBar(tabs:[.....]),
actions: <Widget> [
new PopupMenuButton<xx>()
],),],), //end appBar
drawer: new Drawer(......), //end drawer
body: TabBarView(....), //end body
);
}
to:
Widget build(BuildContext context) {
return new Scaffold(
appBar: _appBar(),
drawer: _drawer(),
body: _body(),
);
}
Widget _appBar() {
return new AppBar(
bottom: new TabBar(tabs:[.....]),
actions: <Widget> [
new PopupMenuButton<xx>()
],),],);
}
Widget _drawer() {
...
}
Widget _body() {
return TabBarView();
}
At this point, you may start to realize what data/state is being passed around as you will have to add parameters to these new helper methods.
If you have a lot of parameter passing (especially on state that changes), you will have other considerations outside the scope of this answer (and we would need to see what state you are actually dealing with).
The next step is to create a new Widget for each of these methods.
From:
Widget _appBar() {
return new AppBar(
bottom: new TabBar(tabs:[.....]),
actions: <Widget> [
new PopupMenuButton<xx>()
],),],);
}
To:
Widget _appBar(...) {
return MyAppBar(...);
}
class MyAppBar extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new AppBar(
bottom: new TabBar(tabs:[.....]),
actions: <Widget> [
new PopupMenuButton<xx>()
],),],);
}
}
You can define MyAppBar
in it's own file.
You can also bypass the _appBar(...)
method and just construct the new widget in the main build()
method (assuming you have no other complex setup):
Widget build(BuildContext context) {
return new Scaffold(
appBar: MyAppBar(),
drawer: MyDrawer(),
body: _body(), // you might want to keep the body in the same file
);
}