Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can someone explain to me what the Builder Class does in Flutter?

The documentation is very confusing and vague. Here is what it states:

Builder class

A platonic widget that calls a closure to obtain its child widget.

Here are my questions:

  1. What do they mean by "platonic"?
  2. What do they mean by "closure"?
  3. What exactly is the purpose of this class?
like image 204
Walter M Avatar asked Aug 30 '18 03:08

Walter M


People also ask

What does Builder do in flutter?

🤔 A builder is a Flutter design pattern in which the construction code of a widget is defined outside of its class. Builder functions are callback interfaces that pass data (often layout-specific) to the parent widget which returns a child based on that data.

What is builder in Dart?

Builder is a creational design pattern, which intention in the GoF book is described like this: Separate the construction of a complex object from its representation so that the same construction process can create different representations.

What is ListView builder in flutter?

ListView is a very important widget in a flutter. It is used to create the list of children But when we want to create a list recursively without writing code again and again then ListView. builder is used instead of ListView. ListView. builder creates a scrollable, linear array of widgets.

What is of () in flutter?

In the Flutter SDK the . of methods are a kind of service locator function that take the framework BuildContext as an argument and return an internal API related to the named class but created by widgets higher up the widget tree.


1 Answers

After long hours of extensive hair-pulling research on the internet, I collected small snippets and combined them to put a cohesive and clear explanation of what the Builder Class does.

Terminology:

According to the official flutter documentation, the Builder Class is defined as:

A platonic widget that calls a closure to obtain its child widget.

Platonic means the simplest possible thing of that kind. The term closure is just another name for a lambda function.

Purpose:

This is going to be a lengthy explanation, but please bear with me:

In the Flutter framework, every widget has a build method that accepts a BuildContext parameter:

Widget build ( BuildContext context ) { ... }

We have to remember that the context object is passed to the widget's build function automatically by the framework. Since the framework takes care of that automatically, there is no reason for any widget to have a constructor or function (aside from build) that would need to accept a context parameter.

Hence, if you were trying to pass a specific context object to a child, you won't be able to. You cannot call build() and pass your own context object manually. I mean, you can, but you would be calling the build function twice:

  1. Your manual call.
  2. The automatic call by the framework.

So, how can we pass a specific context object? This is where the Builder class comes in. The purpose of the Builder class is simply to build and return child widgets. How is that different from any other widget? Aha! The Builder class allows you to pass a specific context object down to its children. The Builder class is basically your own build function that you setup.

Why would I need to pass a specific context object? Lets take a look at an example:

Lets say that we want to add a new SnackBar widget to its new Scaffold parent widget that is being returned:

 @override   Widget build(BuildContext context) {     return new Scaffold(         appBar: new AppBar(           title: new Text(widget.title),         ),         body: new Container(),         /// Scaffold doesn't exist in this context here         /// because the context thats passed into 'build'         /// refers to the Widget 'above' this one in the tree,         /// and the Scaffold doesn't exist above this exact build method         ///         /// This will throw an error:         /// 'Scaffold.of() called with a context that does not contain a Scaffold.'         floatingActionButton: new FloatingActionButton(onPressed: () {           Scaffold.of(context).showSnackBar(                 new SnackBar(                   content: new Text('SnackBar'),                 ),               );         }));   } 

This code above does not work. The Scaffold.of(context) function will not find the Scaffold because:

  1. The Scaffold widget has not been created yet.
  2. The context object that was passed to the build function refers to the parent widget, which is not a Scaffold widget.

So, how do we give the child SnackBar widget access to the parent Scaffold widget? We use a Builder class to pass the context of the Scaffold widget:

 @override   Widget build(BuildContext context) {     return new Scaffold(       appBar: new AppBar(         title: new Text(widget.title),       ),       body: new Container(),       /// Builders let you pass context       /// from your *current* build method       /// Directly to children returned in this build method       ///       /// The 'builder' property accepts a callback       /// which can be treated exactly as a 'build' method on any       /// widget       floatingActionButton: new Builder(builder: (BuildContext context) {         return new FloatingActionButton(onPressed: () {           Scaffold.of(context).showSnackBar(                 new SnackBar(                   backgroundColor: Colors.blue,                   content: new Text('SnackBar'),                 ),               );         });       }),     );   } 

Remember, the Builder class constructor:

Builder({Key key, @required WidgetBuilder builder })

creates a widget by delegating its build to the callback function passed through its constructor.

So, in the code:

new Builder(builder: (BuildContext context){ ... }); 

we provided a closure that:

  1. Contains a BuildContext context parameter
  2. Builds and returns child widget(s) based on that context passed.

Basically, you provided your own build function. The BuildContext context parameter in this closure is the Scaffold's context! Baboom!

That is basically it. The Flutter documentation does not provide a thorough explanation of this at all. I feel like I would have an easier time deciphering ancient hieroglyphs than decoding the Flutter documentation.

I hope this helps anyone that is currently on their tedious journey in learning Flutter.

SUMMARY: For anyone still having a hard time grasping this concept, let me explain in a more concise form. The Builder function simply allows you to attain and use the context object of the widget that the Builder widget is in. In the example above, it is the new Scaffold() widget. Remember, the only context object available to use is that of the parent widget (above Scaffold) since the current widget (Scaffold) has not been created yet. I hope that helps those were still scratching their heads. Cheers!

like image 94
Walter M Avatar answered Oct 15 '22 03:10

Walter M