DEV Community

Cover image for Managing deeply-nested Flutter files
Moses Karunia
Moses Karunia

Posted on

Managing deeply-nested Flutter files

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();
            ],
          );
        }
      );
    );
  }
}
Enter fullscreen mode Exit fullscreen mode
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
  }
}
Enter fullscreen mode Exit fullscreen mode
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
  }
}
Enter fullscreen mode Exit fullscreen mode

Here are the steps:

  1. Put the complex widget into its own folder (my_widget/my_widget.dart)
  2. 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 _)
  3. 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!

Cover image provided by www.freepik.com

Top comments (2)

Collapse
 
mdev88 profile image
Martín Vukovic

Nice, I didn't know about the part and part of keywords. Thanks.

Collapse
 
jamesshaun9 profile image
James Shaun

nice post