Paramclasses Academy - Blog

Tutorials Details

←
Post 13 of 40
→

Flutter Widgets Explained: StatelessWidget vs StatefulWidget

Flutter Widgets Explained: StatelessWidget vs StatefulWidget

November 2, 2026

Flutter Widgets Explained: StatelessWidget vs StatefulWidget

❖ Welcome to Param Classes!

Welcome to Param Classes! In our previous tutorials, we learned how to create Flutter projects, run applications on Android devices and use Hot Reload and Hot Restart.

Now we will learn one of the most important concepts in Flutter development: Widgets.

Everything you see in a Flutter application is built using widgets. Text, buttons, images, app bars, layouts and even complete screens are represented by widgets.

Flutter mainly provides two important widget types for building user interfaces:

  • StatelessWidget

  • StatefulWidget

In this tutorial, we will understand both widgets, learn their differences and create practical Flutter examples step by step.

✦ 1. What Are Widgets in Flutter?

A widget is a building block of a Flutter user interface.

You can think of widgets as components used to design an application screen.

For example, a simple login screen may contain:

  • Text widget for headings.

  • TextField widget for user input.

  • ElevatedButton widget for login.

  • Image widget for a logo.

  • Column widget for vertical arrangement.

  • Container widget for styling.

Flutter combines these widgets to create complete application screens.

Example:

import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: Center(
          child: Text("Welcome to Flutter"),
        ),
      ),
    );
  }
}

In this example:

  • MaterialApp provides the application structure.

  • Scaffold provides the screen layout.

  • Center positions its child in the center.

  • Text displays a message.

Each of these is a widget.

✦ 2. What Is StatelessWidget in Flutter?

A StatelessWidget is a widget that does not manage its own changing state.

It is suitable for displaying content that does not need to change internally in response to user interaction or other changing data.

For example:

  • Static headings.

  • Welcome messages.

  • Logos.

  • Fixed icons.

  • Information labels.

Example:

import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: Scaffold(
        appBar: AppBar(
          title: const Text("StatelessWidget Example"),
        ),
        body: const Center(
          child: Text(
            "Welcome to Param Classes",
            style: TextStyle(
              fontSize: 24,
              fontWeight: FontWeight.bold,
            ),
          ),
        ),
      ),
    );
  }
}

Explanation:

  1. MyApp is a class.

  2. It extends StatelessWidget.

  3. The constructor creates the widget.

  4. The build() method describes the user interface.

  5. The Text widget displays a message.

The displayed message is fixed in this example. The widget does not manage its own changing state.

✦ 3. What Is StatefulWidget in Flutter?

A StatefulWidget is a widget that has a separate State object to manage changing data.

It is useful when the user interface needs to update because of user actions or changing application data.

For example:

  • Counter applications.

  • Like buttons.

  • Login forms.

  • Checkboxes.

  • Switches.

  • Interactive screens.

When the state changes, Flutter can rebuild the relevant part of the user interface.

Example: Counter Application

import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      debugShowCheckedModeBanner: false,
      home: CounterScreen(),
    );
  }
}

class CounterScreen extends StatefulWidget {
  const CounterScreen({super.key});

  @override
  State<CounterScreen> createState() {
    return _CounterScreenState();
  }
}

class _CounterScreenState extends State<CounterScreen> {

  int counter = 0;

  void increaseCounter() {
    setState(() {
      counter++;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text("StatefulWidget Example"),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            const Text(
              "Counter Value",
              style: TextStyle(fontSize: 22),
            ),

            const SizedBox(height: 15),

            Text(
              "$counter",
              style: const TextStyle(
                fontSize: 40,
                fontWeight: FontWeight.bold,
              ),
            ),

            const SizedBox(height: 20),

            ElevatedButton(
              onPressed: increaseCounter,
              child: const Text("Increase"),
            ),
          ],
        ),
      ),
    );
  }
}

How does this application work?

  • CounterScreen is a StatefulWidget.

  • _CounterScreenState stores the changing counter value.

  • counter starts at zero.

  • increaseCounter() increases the value.

  • setState() tells Flutter that the state has changed.

  • Flutter rebuilds the widget to display the updated counter.

Every time you press the Increase button, the counter value increases.

✦ 4. What Is setState() in Flutter?

setState() is a method used inside a State object to notify Flutter that the internal state has changed.

Flutter then schedules a rebuild so the updated information can be displayed.

Example:

setState(() {
  counter++;
});

Here, the counter value increases by one.

Without calling setState() for this change, Flutter may not rebuild the interface to show the new value.

Important: Use setState() for changes to the state managed by that particular StatefulWidget. For larger applications, other state management approaches may be more suitable.

✦ 5. Difference Between StatelessWidget and StatefulWidget

Both widgets are important, but they serve different purposes.

Feature StatelessWidget StatefulWidget
State management Does not manage its own mutable state Uses a separate State object
UI updates Rebuilds when its inputs or dependencies change Can rebuild when its state changes
setState() Not available directly Available in its State class
Best for Static or input-driven UI Interactive and changing UI
Example Fixed text or logo Counter or checkbox

Simple Example:

  • A company logo displayed on a screen can use StatelessWidget.

  • A button that changes a counter value can use StatefulWidget.

Choosing the correct widget helps keep your Flutter application organized.

✦ 6. Understand the StatefulWidget Lifecycle

A StatefulWidget has a lifecycle that helps Flutter manage its state.

The widget class and its State object have different responsibilities.

Some important lifecycle methods are:

❖ A. createState()

This method creates the State object for a StatefulWidget.

@override
State<MyWidget> createState() => _MyWidgetState();

❖ B. initState()

initState() is called when the State object is inserted into the widget tree for the first time.

It is commonly used for one-time initialization.

@override
void initState() {
  super.initState();

  print("Widget Initialized");
}

❖ C. build()

The build() method describes the user interface.

It can be called multiple times when Flutter needs to rebuild the widget.

@override
Widget build(BuildContext context) {
  return const Text("Hello Flutter");
}

❖ D. dispose()

dispose() is called when the State object is permanently removed from the widget tree.

It is commonly used to clean up resources such as controllers and listeners.

@override
void dispose() {
  super.dispose();
}

Note: These methods are part of the State lifecycle. You should call super.initState() and super.dispose() when overriding them.

✦ 7. Practical Example: Like Button Using StatefulWidget

Let's create a simple Like button.

When the user clicks the button, the like count will increase.

Complete Code:

import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      debugShowCheckedModeBanner: false,
      home: LikeScreen(),
    );
  }
}

class LikeScreen extends StatefulWidget {
  const LikeScreen({super.key});

  @override
  State<LikeScreen> createState() => _LikeScreenState();
}

class _LikeScreenState extends State<LikeScreen> {

  int likes = 0;

  void addLike() {
    setState(() {
      likes++;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text("Like Button Example"),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            const Icon(
              Icons.favorite,
              color: Colors.red,
              size: 70,
            ),

            const SizedBox(height: 15),

            Text(
              "Likes: $likes",
              style: const TextStyle(
                fontSize: 25,
                fontWeight: FontWeight.bold,
              ),
            ),

            const SizedBox(height: 20),

            ElevatedButton.icon(
              onPressed: addLike,
              icon: const Icon(Icons.thumb_up),
              label: const Text("Like"),
            ),
          ],
        ),
      ),
    );
  }
}

Expected Result:

  • A heart icon appears on the screen.

  • The initial like count is zero.

  • Pressing the Like button increases the count.

  • The screen displays the updated value.

This is a simple example of using StatefulWidget to create an interactive application feature.

✦ 8. Can StatelessWidget and StatefulWidget Work Together?

Yes! In fact, Flutter applications commonly use both types of widgets together.

For example, a StatefulWidget can manage a changing counter, while a separate StatelessWidget displays a fixed heading.

Example:

import 'package:flutter/material.dart';

class CounterTitle extends StatelessWidget {
  const CounterTitle({super.key});

  @override
  Widget build(BuildContext context) {
    return const Text(
      "My Counter App",
      style: TextStyle(
        fontSize: 24,
        fontWeight: FontWeight.bold,
      ),
    );
  }
}

You can use this widget inside the build() method of your counter screen:

const CounterTitle(),

This approach allows you to reuse UI components and keep your code clean.

✦ 9. When Should You Use Each Widget?

Choosing the right widget depends on what your screen needs to do.

Use StatelessWidget when:

  • You want to display fixed content.

  • Your widget does not manage changing state.

  • You are creating reusable display components.

  • The UI depends on values passed from a parent widget.

Use StatefulWidget when:

  • The widget needs to manage changing data.

  • A button updates information on the screen.

  • A checkbox or switch changes its value.

  • You need to manage controllers or other state-related resources.

Remember, a StatelessWidget can still rebuild when its parent provides new inputs. Stateless means it does not manage its own mutable state.

✦ 10. Common Mistakes Beginners Should Avoid

1. Using StatelessWidget for Locally Changing State

If a widget needs to manage changing values internally, consider StatefulWidget or another appropriate state management solution.

2. Forgetting setState()

Changing a variable alone does not automatically tell Flutter to rebuild the interface.

3. Writing Too Much Code in One Widget

Break larger interfaces into smaller reusable widgets.

4. Forgetting to Clean Up Resources

Dispose of controllers and listeners when they are no longer needed.

5. Confusing Widget and State

A StatefulWidget configuration and its State object are separate parts of Flutter's widget system.

✦ 11. Practice Tasks for Beginners

Try these practical exercises:

  1. Create a StatelessWidget that displays your name.

  2. Create a StatefulWidget with a counter.

  3. Add an Increase and Decrease button.

  4. Create a Like button that updates the number of likes.

  5. Create a checkbox that changes its selected value.

  6. Display a fixed heading using a separate StatelessWidget.

  7. Use both widget types together in one application.

❖ Conclusion

Widgets are the foundation of Flutter application development.

In this tutorial, we learned what widgets are, how StatelessWidget and StatefulWidget work, how to use setState(), and how the StatefulWidget lifecycle operates.

We also created practical examples using a counter and a Like button.

At Param Classes, we believe that understanding the basics through practical examples makes learning Flutter easier. Practise both widget types before moving towards advanced layouts and application development.

Keep Learning with Param Classes — Learn Today, Grow Tomorrow!

←
Post 13 of 40
→