Understanding Flutter Widgets with Code Examples

Understanding flutter widgets, stateless and stateful widgets

In this post, we will understand some of the following key concepts of Flutter framework.

  • What are widgets?
  • What are stateless widgets?
  • What are stateful widgets?

A flutter mobile app consists of multiple UIs with each UI built out of one or more widgets. These widgets are nothing but elements of interaction between the app user and the application. Note element of interaction used to describe widget in Wikipedia definition given below.

As per the wikipedia, A graphical widget (also graphical control element or control) in a graphical user interface is an element of interaction such as a button or a scroll bar. Controls are software components that a computer user interacts with through direct manipulation to read or edit information about an application.

Widgets represent a view with a configuration and a state. A widget is built with some configuration and state. The code sample below represents build method which is nothing but a way to build the widget. The build method returns an instance of Widget. This method, in turn, is responsible for building the widget with the help of one or more child widgets. 

class MyApp extends StatelessWidget {
    @override
    Widget build(BuildContext context) {
        return ...
    }
}
Widget tree representing parent and child widgets
Fig 1. Widget tree representing parent and child widgets

The above represents a container widget which is built when the app gets loaded. The animated image below represents the UI built using widgets.

Fig 2. App UIs and widgets

As described above, the widgets represent a view with a configuration and a state. We also saw that widgets are nothing but elements of interaction which allows users to interact with the app. But widgets are configuration of what? Widgets are configuration of what is called as Elements. What is shown on App’s UI is set of elements in form of the elements’ tree which is associated with the respective widget tree. Each element is associated with a widget having configuration and a state.

How the Flutter app loads the UI in form of elements and widgets?

When an app is loaded, Flutter asks widgets for its associated elements which results in loading elements tree. Widget creates an element and the element is mounted on the element tree. The element tree then gets displayed on the UI. Each element in the tree references its associated widgets for configuration and state information.

Note that it is the element tree which represents what is displayed on the screen. Elements references widgets which are nothing but blueprints for those elements.

At any point, a flutter app has got two trees. One of them is element tree which gets loaded on screen and help users interacts with the app. And, the another is widgets tree which holds the configuration and state information for those elements. The diagram below represents a sample app with two trees.

Fig 3. Elements and Widgets Tree for an app

What are Stateless Widgets?

Stateless widgets are the immutable configuration or blueprint which once built does not change. Once loaded, their state information don’t change. An example of stateless widget is the following. We will deal with stateless widgets in detail in another post.

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Center(
        child: Text(
          'Hello World',
          textDirection: TextDirection.ltr,
        )
    );
  }
}

Here is a picture representing the widgets tree vis-a-vis elements tree starting with stateless element at root node. Note that the stateless element can go one to build stateful element which could build itself with a set of stateless widget etc.

Fig 4. Element tree vis-a-vis widgets tree

Here is another code example of stateless widgets:

class ItemCounter extends StatelessWidgets {
    final String name;
    final int count;

    ItemCounter({this.name, this.count});

    @override
    Widget build(BuildContext context) {
        return Text('$name: $count')
    }
}

What are Stateful Widgets?

Stateful widgets are the ones whose state changes. For stateful widgets, one needs to create two different objects.

  • A widget object which consists of immutable configuration
  • A state object which consists of state

We will deal with stateful widgets in detail in another post.

class RandomWords extends StatefulWidget {
  @override
  _RandomWordsState createState() => _RandomWordsState();
}

class _RandomWordsState extends State<RandomWords> {
    @override
    Widget build(BuildContext context) {
      final wordPair = WordPair.random();
      return Text(wordPair.asPascalCase);
    }
  }

Note the following in the above code:

  • Widget RandomWords extends StatefulWidget class
  • createState() method is used to create the state represented using another class of type State<RandomWords>. Stateful widgets are responsible for holding on to immutable configuration and creating a state object
  • build method is used to maintain the state within the state class represented using _RandomWordsState

Taking the ItemCounter example under Stateless Widget, lets see how to change it into a stateful widget where the configuration (count) becomes mutable and a state is maintained.

class ItemCounter extends StatelessWidgets {
    final String name;

    ItemCounter({this.name});

    @override
    _ItemCounterState createState() => _ItemCounterState();
}

class _ItemCounterState extends State<ItemCounter> {
    int count = 0;

    @override
    Widget build(BuildContext context) {
        return Text('${widget.name}: $count')
    }
}

In above code, notice that ItemCounter is a stateful widget which does two things:

  • Hold on to immutable configuration such as name
  • Create a state object of type _ItemCounterState
  • Use build method of state object to display widget content

This is what happens internally during creation of stateful widgets:

  • A stateful widget creates a stateful element
  • The stateful element asks widget to create a state object. It then attaches with the reference of state object passed by the widget.
  • The stateful widget then creates the child widget by invoking the build method of state object.

The above is displayed in the diagram below:

In this post, you learnt about widgets and different types of widgets. I will follow up with further examples related to stateful and stateless widgets.

Ajitesh Kumar

Ajitesh Kumar

I have been recently working in the area of Data analytics including Data Science and Machine Learning / Deep Learning. I am also passionate about different technologies including programming languages such as Java/JEE, Javascript, Python, R, Julia, etc, and technologies such as Blockchain, mobile computing, cloud-native technologies, application security, cloud computing platforms, big data, etc. I would love to connect with you on Linkedin. Check out my latest book titled as First Principles Thinking: Building winning products using first principles thinking.
Posted in Flutter. Tagged with , , .