ARTICLE

From Flutter in Action by Eric Windmill

This article is a crash course on widgets in Flutter.

__________________________________________________________________

Take 37% off Flutter in Action. Just enter fccwindmill into the discount code box at checkout at manning.com.
__________________________________________________________________

Widgets: The widget tree, widget types and the State object

In general, Flutter is made of a handful of widget types. The two which we care about right now are the base of all other widget types — StatelessWidget and StatefulWidget.

The general goal when developing UI in a Flutter app is to compose a ton of widgets together to build the widget tree. A Flutter app is represented by a widget tree, similar to the DOM on the browser, which is also a tree-structure.

Here’s a simple visual representation of the widget tree for the counter app:

Image for post
Image for post

The process of composing widgets together is done by telling widgets that their child (or children) are more widgets. A simple example is styling some text:

return Container(     child: Padding( ①
padding: EdgeInsets.all(8.0),
child: Text("Padded Text") ②
),
);

① The container widget has a property called child, which takes another widget.

② The Padding widget has a property called child also, which takes a widget.

Other common properties in Flutter that allow you to pass widgets into widgets are children and builder.

Stateless Widget

The difference between a StatefulWidget and a StatelessWidget is right in the name. A StatefulWidgettracks its own internal state. A StatelessWidget is a “dumb” widget. It doesn’t care about its configuration or what data it’s displaying. It could be passed a configuration from its parent, or the configuration could be defined within the widget, but it can’t change its own configuration. A stateless widget’s immutable.

When it comes to widget jargon, you’ll see the word configuration often.

NOTE: it’s vague, but it encapsulates everything: namely the variables passed in and its size constraints (enforced by its parent).

Imagine a button in your app. Perhaps it always says “Submit”:

class SubmitButton extends StatelessWidget {   Widget build(context) {
return Button(
child: Text('Submit');
);
}
}

Or, perhaps you want the button to say “Submit” in some cases and “Update” in others.

Listing 1. A widget with configuration

class SubmitButton extends StatelessWidget {   final String buttonText;                                                      ①
SubmitButton(this.buttonText); ②
Widget build(context) {
return Button(
child: Text(buttonText); ③
);
}
}

① Any piece of data passed to the widget is part of its configuration.

② You can omit useless constructors in Dart, but it’s needed now.

③ Pass in a variable, rather than a string literal. Flutter now knows to change this widget whenever configuration changes.

Either way, this widget is ‘dumb’ because it doesn’t update itself. It doesn’t care what the button says. Its configuration relies on parent widgets.

Also, importantly, StatelessWidgets are destroyed entirely when Flutter removes them from the widget tree. It’s important to understand that a Stateless widget shouldn’t be responsible for any data you don’t want to lose. Once it’s gone, it’s gone.

Stateful Widget

A StatefulWidget has internal state and can manage that state. All StatefulWidgets have corresponding State objects. This is the anatomy of every StatefulWidget.

Listing 2. Anatomy of a Stateful Widget

class MyHomePage extends StatefulWidget {                    ①
@override ②
_MyHomePageState createState() => new _MyHomePageState(); ③
}
class _MyHomePageState extends State<MyHomePage> { ④
@override
Widget build(BuildContext context) { ⑤
// ..
}
}

① Inherit from StatefulWidget

② Override the super class method createState

③ Every StatefulWidget must have a createState method which returns a State object

④ Your state class inherits from the Flutter State object

⑤ The StatefulWidget required build method.

If you remember earlier, I said that every widget class must have a build method. As you can see above, the StatefulWidget class, in fact, doesn’t have a build method. Every StatefulWidget has an associated Stateobject, which has a build method. You can think of the pair of StatefulWidget and State as the same entity. In fact, Stateful widgets are dumb and immutable (like a StatelessWidget), but their associated State objects are smart and mutable.

MyHomePage is a StatefulWidget, because it manages the state of the counter in the center of the app. When you tap that button, it fires a method called _incrementCounter.

void _incrementCounter() {   setState(() { ①
_counter++;
});
}

setState is one of the methods that a Flutter State object uses to manage internal state.

Image for post
Image for post

setState

setState is the third important Flutter method that you have to know, after build and createState. It only exists on the State object. It more or less says “Hey Flutter, execute the code in this callback, (in this case, increase the counter variable by one), and then repaint all the widgets that rely on this state for configuration (in this case, the number on the screen in the middle of the app).” This method takes one argument, a void callback.

In our example, the State object lives in the _MyHomePageState widget, and its children interact and rely on the state. When you press the button, it calls a method passed to it from _MyHomePageState. That method calls setState, which in turn calls the _MyHomePageState.build method again, repainting the widgets whose configurations have changed.

Image for post
Image for post

This covers setState, but it’s worth noting that setState can’t execute async code. Any async work should be done before calling setState, because you don’t want Flutter to repaint something before the data it’s meant to display has resolved. For example, if you’re fetching a gif from a gif API on the internet, you don’t want call setState before the image is ready to displayed.

That’s all for now. If you want to learn more about the book, check it out on liveBook here and see this slide deck.

For more free content from Manning’s books and video courses, check out our Free Content Center.

Written by

Follow Manning Publications on Medium for free content and exclusive discounts.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store