mike hennessy
mike hennessy

Reputation: 1679

Extracting Class Members like Widget Builders to a Different File?

In developing some of the screens for my flutter app, I regularly need to dynamically render widgets based on the state of the screen. For circumstances where it makes sense to create a separate widget and include it, I do that.

However, there are many use cases where what I need to render is not fit for a widget, and leverages existing state from the page. Therefore I use builder methods to render the appropriate widgets to the page. As anyone who uses Flutter knows, that can lead to lengthy code where you need to scroll up/down a lot to get to what you need to work on.

For better maintainability, I would love to move those builder methods into separate files, and then just include them. This would make it much easier to work on specific code widgets rendered and make the screen widget much cleaner.

But I haven't found a proper way to extract that dynamic widget code, which makes use of state, calls to update state, etc. I'm looking for a type of "include" file that would insert code into the main screen and render as if it's part of the core code.

Is this possible? How to achieve?

Upvotes: 2

Views: 828

Answers (1)

creativecreatorormaybenot
creativecreatorormaybenot

Reputation: 126664

With the introduction of extension members, I came across this really neat way of achieving exactly what your described!

Say you have a State class defined like this:

class MyWidgetState extends State<MyWidget> {
  int cakes;

  @override
  void initState() {
    super.initState();

    cakes = 0;
  }

  @override
  Widget build(BuildContext context) {
    return Builder(
      builder: (context) => Text('$cakes'),
    );
  }
}

As you can see, there is a local variable cakes and a builder function. The very neat way to extract this builder now is the following:

extension CakesBuilderExtension on MyWidgetState {
  Widget cakesBuilder(BuildContext context) {
    return Text('$cakes');
  }
}

Now, the cakes member can be accessed from the extension even if the extension is placed in another file.

Now, you would update your State class like this (the builder changed):

class MyWidgetState extends State<MyWidget> {
  int cakes;

  @override
  void initState() {
    super.initState();

    cakes = 0;
  }

  @override
  Widget build(BuildContext context) {
    return Builder(
      builder: cakesBuilder,
    );
  }
}

The cakesBuilder can be referenced from MyWidgetState, even though it is only declared in the CakesBuilderExtension!

Note

The extension feature requires Dart 2.6. This is not yet available in the stable channel, but should be around the end of 2019 I guess. Thus, you need to use the dev or master channels: flutter channel dev or flutter channel master and update the environment constraint in your pubspec.yaml file:

environment:
  sdk: '>=2.6.0-dev.8.2 <3.0.0'

Upvotes: 3

Related Questions