Managing deeply-nested Flutter files
Moses Karunia
Posted on August 7, 2020
One of many common problems a Flutter developer might face is that their widget files are easy to get crazily deeply-nested. This pose a problem because a deeply nested widgets are relatively harder to read.
One of the solution is to break it into separate, smaller chunk of widget. This way, you can maximize readability by containerizing each widget based on its functionality.
That's a good solution, but for me it's not optimal, because now, there are a lot of separate one-use widgets scattered in our project folder. One of the problem is it makes my naming harder, and it clutters my VS Code autocomplete.
So, it'll be better if we can break our deeply-nested widget file, without it clutters our IDE / editor autocomplete.
This is where I used part
and part of
directive.
This is an example of how I structure my files:
File: lib/widgets/my_widget/my_widget.dart
/// Import declarations
part 'my_top_widget.w.dart';
part 'my_center_widget.w.dart';
part 'my_bottom_widget.w.dart';
class MyWidget extends StatelessWidget {
@override
Widget build (BuildContext context) {
return Scaffold (
body: LayoutBuilder(
build: (context, boxConstraints) {
return ListView(
children: <Widget> [
_$MyFirstSubwidget();
_$MySecondSubwidget();
],
);
}
);
);
}
}
File: lib/widgets/my_widget/my_first_widget.w.dart
/// A "Part of" file cannot have its own import declarations
part of 'my_widget.dart';
class _$MyFirstWidget extends StatelessWidget {
@override
Widget build (BuildContext context) {
// TODO: Return widget
}
}
File: lib/widgets/my_widget/my_second_widget.w.dart
/// A "Part of" file cannot have its own import declarations
part of 'my_widget.dart';
class _$MySecondWidget extends StatelessWidget {
@override
Widget build (BuildContext context) {
// TODO: Return widget
}
}
Here are the steps:
- Put the complex widget into its own folder (my_widget/my_widget.dart)
- Prefixing the sub-widgets name with
_$
(You don't need the dollar$
sign. It's just my way to differ it with a class-level private. The key is to make it private with_
) - Postfix sub-widget file name with
*.w.dart
. It's just my personal convention to say that a widget is a sub-widget of another widget.
I would also like to add, that by postfixing your sub-widget files with *.w.dart
, you can also make similar separate file for your helper function with *.u.dart
, where u stands for utility. Again, you can choose whatever postfix you like.
Bonus advantage is, by using this approach, you can easily move the sub-widget out of the folder in case you need it to use it in another main widget. (Too many early refactors are not good)
Hope this tip helps you make flutter files more readable.
Cheers!
Posted on August 7, 2020
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.