Why we need Stateful Widget in Flutter

What is the role of variable in Flutter? In the previous section we have seen that. However, the demonstration was simple. We cannot change the variables dynamically. In fact, to do that we needed a Stateful Widget in Flutter.

We have not discussed Stateful Widget before. Although we have learned how a Class extends and inherits properties from its parent.

As a result, we have built a Flutter App or Widget tree that extends Stateless Widgets only.

Why?

Because our previous Flutter Apps did not have to interact with the users. A user could only see the App. There were no opportunities to interact with the App.

If we want to make our Flutter App interactive, we need Stateful Widgets.

Moreover, we need to understand what is State in Flutter.

In general, what does the word “State” mean? It means – a particular condition that refers to a specific time which changes.

Since time is involved, it also refers to a change.

Let us consider some concrete examples. You may have visited a website where you can only read. In such cases, we say that the website is not an interactive one. It is stateless.

On the contrary, every E-Commerce website allows us to interact. We can add to cart.

And, after that, we an either buy the product, or remove the item from the cart.

In other words, the website is interactive or stateful.

With reference to the previous discussion, we can say the following.

When a variable changes its value dynamically, it also changes its state. In addition it changes the State of the Widget where it belongs to.

State always refers to Change.

What is stateful flutter?

In one sentence, a Stateful Widget is a Dynamic Widget. Based on user’s action, the Stateful Widget changes its State. In other words, it updates its value.

In the previous section we have built a simple Photo App. We have also learned what is anonymous function in Flutter.

Anonymous function Example in Flutter
Anonymous function Example in Flutter

However, we cannot interact with this Flutter App. Right?

If we tap any one of the images, nothing happens. Again we repeat, it is not interactive. Or Stateful.

Why? Because we have inherited from a Stateless Widget.

We can take a look at the code snippet.

import 'package:flutter/material.dart';

class AppHomePage extends StatelessWidget {
  const AppHomePage({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    
    List name = ['greedy', 'confident', 'careless'];

    return Scaffold(
      backgroundColor: Colors.white70,
      appBar: AppBar(
        title: const Text('Anonymous Function Example'),
      ),
      body: Center(
        child: Row(
          children: [
            Expanded(
              child: Padding(
                padding: const EdgeInsets.all(18.0),
                child: GestureDetector(
                  onTap: () {
                    print('I am Greedy 3D Buddy.');
                  },
                  child: Image.asset('images/${name[0]}.jpg'),
                ),
              ),
            ),
            Expanded(
              child: Padding(
                padding: const EdgeInsets.all(18.0),
                child: GestureDetector(
                  onTap: () {
                    print('I am Confident 3D Buddy');
                  },
                  child: Image.asset('images/${name[1]}.jpg'),
                ),
              ),
            ),
            Expanded(
              child: Padding(
                padding: const EdgeInsets.all(18.0),
                child: GestureDetector(
                  onTap: () {
                    print('I am Careless 3D Buddy.');
                  },
                  child: Image.asset('images/${name[2]}.jpg'),
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

Although we have used a GestureDetector Widget, and have had the “onTap” VoidCallback property, still we have not added any interactivity.

If we can change the index number of the list from 0 to 1, or 2, the image changes. Right?

In fact, the primary job of a function is exactly the same. Any function, or method changes the state of the variable, or field.

In the above code, it does not happen.

What is stateful and stateless in flutter?

The Stateless Widget remains immutable. It does not change. That also includes the variable.

However, the Stateful Widget we can do that with the help of a special method – setState().

Let us change the above code to a Stateful Widget.

import 'package:flutter/material.dart';

class AppHomePage extends StatefulWidget {
  const AppHomePage({Key? key}) : super(key: key);

  @override
  State<AppHomePage> createState() => _AppHomePageState();
}

class _AppHomePageState extends State<AppHomePage> {
  List name = ['greedy', 'confident', 'careless'];
  int index = 0;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.white70,
      appBar: AppBar(
        title: const Text('Stateful Photo App'),
      ),
      body: Center(
        child: Row(
          children: [
            Expanded(
              child: Padding(
                padding: const EdgeInsets.all(18.0),
                child: GestureDetector(
                  onTap: () {
                    setState(() {
                      index++;
                      if (index == 3) {
                        index = 0;
                      }
                    });
                  },
                  child: Image.asset('images/${name[index]}.jpg'),
                ),
              ),
            ),
            Expanded(
              child: Padding(
                padding: const EdgeInsets.all(18.0),
                child: GestureDetector(
                  onTap: () {
                    setState(() {
                      index++;
                      if (index == 3) {
                        index = 0;
                      }
                    });
                  },
                  child: Image.asset('images/${name[index]}.jpg'),
                ),
              ),
            ),
            Expanded(
              child: Padding(
                padding: const EdgeInsets.all(18.0),
                child: GestureDetector(
                  onTap: () {
                    setState(() {
                      index++;
                      if (index == 3) {
                        index = 0;
                      }
                    });
                  },
                  child: Image.asset('images/${name[index]}.jpg'),
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

Now look at the onTap property of the GestureDetector Widget.

We have used the onTap property that returns a setState() method.

setState(() {
                      index++;
                      if (index == 3) {
                        index = 0;
                      }
                    });

Inside the “setState” method index is increasing by 1. But, at the same time, we have used a logic that restricts the index number.

So that the index number does not go past 2.

When it reaches 3, it comes down to 0 again.

As a result, when we can now click any image and it changes the index number.

Stateful Photo App Sample One
Stateful Photo App Sample One

Click any one of the above image. That will make the index number 2.

As a consequence, the second image will appear on the screen.

Stateful Photo App Sample Two
Stateful Photo App Sample Two

We can apply the same logic again.

Click any image and it changes the index number to 3.

Stateful Photo App Sample Three
Stateful Photo App Sample Three

Clicking any image makes the index number 0 again. Moreover, whenever we click the image the build() method builds the Widget with updated value.

Although it is not a great App, yet we have accomplished a new task.

We have been able to change the state of the Widget. Not only that, we have learned why we need Stateful Widget. However, the concept involving the State does not end here.

Therefore we will come back and discuss more.

Since this write-up aims at providing clarification for the beginners, we will not delve more.

However, in the next section, we will try to make it more profound using the Dart Mathematics library.

We will try to randomize the index number. Consequently the index number will not change from 0 to 1. But it may change from 0 to 2. Meanwhile we can add more images to make it look interesting.

So stay tuned. Happy Fluttering.

What Next?

Books at Leanpub

Books in Apress

My books at Amazon

GitHub repository

Technical blog

Twitter

Comments

3 responses to “Why we need Stateful Widget in Flutter”

  1. […] us see the code snippet of “Mood Swing App”. Because we had used the Stateful Widget, we had to use setState() method that stores the change of the […]

  2. […] see a simple Stateful widget where we have used a counter to press the button and change the internal state of the […]

  3. […] our previous section we have seen a simple Stateful widget where we have used a counter to press the button and change the internal state of the object. As a […]

Leave a Reply