Reputation: 3229
Consider the following code:
import 'package:flutter/material.dart';
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'Welcome to Flutter',
home: new Scaffold(
appBar: new AppBar(
title: new Text('Welcome to Flutter'),
),
body: new Center(
child: new Text('Hello World'),
),
),
);
}
}
My understanding of Buildcontext is that it is the "context" of the widget (please correct me if I'm wrong or elaborate further). What I don't understand is how is the argument "context" passed into the method. Does the runApp function supply the "context"?
Upvotes: 1
Views: 1227
Reputation: 4405
TLDR: This is controlled by the framework.
For those who like reading:
Starting from the very beginning. The runApp
method takes your app widget and inserts it into the tree, as per comment on the method (binding.dart):
Inflate the given widget and attach it to the screen.
When that's being done, the app StatelessWidget
(which obviously is a Widget
) is being inflated into an Element
(Widget
class comments in framework.dart file)
Each time a widget is placed in the tree, it is inflated into an [Element], which means a widget that is incorporated into the tree multiple times will be inflated multiple times.
If you then have a look at the abstract class Element
, in the same GitHub repo file (framework.dart), you will see the comments above it, saying:
Elements have the following lifecycle:
- The framework creates an element by calling [Widget.createElement] on the widget that will be used as the element's initial configuration.
- The framework calls [mount] to add the newly created element to the tree at a given slot in a given parent. The [mount] method is responsible for inflating any child widgets and calling [attachRenderObject] as necessary to attach any associated render objects to the render tree.
These two methods createElement
and mount
are the ones that are responsible for calling the build
method.
If you have a look at the the StatelessWidget
class, you will see that it has an override for createElement
method (framework.dart). Which creates StatelessElement
object and passes itself (this
) as a constructor parameter. Notice, how the StatelessElement
class overrides the build
method and calls widget.build
method (in this case, the widget
is your app widget - i.e. MyApp
). This still doesn't tell us how the build
method is called though. If you drill down a bit deeper, into the ComponentElement
(class that StatelessElement
derives from - framework.dart), you can see the mount
method being overridden. In this method (which is invoked by the framework), there's a call to _firstBuild
method, which then calls rebuild
, this method then calls performRebuild
method, which finally ends up invoking the build
method.
Easy, right?
DISCLAIMER: This is just me connecting the dots. I'm not an expert on Flutter - I literally started using Flutter a week ago. It would be good if some more experienced devs could confirm or not, if my understanding of the mechanisms behind widgets is correct.
EDIT: Answering comment questions
Inflating (in my mind) is creating the object in the memory (so that framework has a reference of it) and rendering it on the screen.
Yes, the BuildContext
is going to be the StatelessElement
, which contains a reference to the app itself
Upvotes: 5