Flutter Introduction | Using the State Class and Understanding StatefulWidget!!
In this article, we will explain StatefulWidget and create an app where the display dynamically changes when a button is pressed!!
Table of contents
- About StatefulWidget
- Manipulating State in StatefulWidget
- Handling FloatingActionButton Tap
- Using Complex Values
- summary
About StatefulWidget
The StatelessWidget we used in the previous article is a widget that does not have a state.
State is a mechanism for maintaining the state of an application.
In other words, if there is no state, the widget remains in the same condition as when it was first displayed and does not change.
However, in real applications, it is natural for the display to change dynamically.
An app that updates its display dynamically cannot be created using StatelessWidget.
That’s why we use StatefulWidget, which we will explain in this article.
StatefulWidget and State
The StatefulWidget class has the ability to handle state.
This functionality is provided by the State class.
To summarize, a StatefulWidget is defined in the following structure:
Basic Structure of a StatefulWidget Class
class widgetClass extends StatefulWidget {
@override
State<widgetClass> createState() => stateClass();
}
Basic Structure of the State Class
class stateClass extends State<widgetClass> {
…Omitted…
@override
Widget build(BuildContext context) {
…Omitted…
}
}
The StatefulWidget class consists of two parts:
- State part (State class) – Manages the state and updates the UI when necessary.
- Widget part (StatefulWidget class) – Defines the structure of the widget.
Widget Class
The widget class is defined by extending the StatefulWidget class.
This class must implement the createState method.
The createState method is responsible for creating the state, and typically, it simply returns an instance of the state class.
State Class
The state class is created by extending the State class.
When defining it, the widget class should be specified inside < >.
This links the state class to the corresponding StatefulWidget.
The state class includes a build method.
The build method is called when the state is created and returns the widget that represents the current state.
In the widget class, the createState method returns an instance of the state class.
This instance is then used in the state class, where the build method generates the widget.
As a result, the widget created in the state class‘s build method is displayed on the screen as the UI of the widget class.
The build method is called frequently in Flutter
Do not think of build as being called only when the instance is created.
Instead, understand it as a method of the State class responsible for generating the UI.
The build method is also called whenever the state is updated—for example, when setState is used to modify a value. It then recreates the UI and updates the display accordingly.
Manipulating State in StatefulWidget
Now, let’s implement a sample to manipulate the state.
Rewrite main.dart as follows.
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
final title = 'Flutter sample';
final message = 'sample message';
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
home: new MyHomePage(title: this.title, message: this.message),
);
}
}
class MyHomePage extends StatefulWidget {
final String title;
final String message;
const MyHomePage({super.key, required this.title, required this.message});
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Text(
widget.message,
style: TextStyle(fontSize: 32.0),
));
}
}
When you run the program, a simple message is displayed.

This displays the screen using state, but no logic has been implemented yet to manipulate the state.
For now, it’s just a sample to demonstrate what a StatefulWidget looks like.
Linking with the State Class
Here, the MyHomePage widget class is created as a StatefulWidget.
Additionally, the _MyHomePageState state class is defined and set as the state for MyHomePage.
Looking at the createState method, we can see the following implementation:
@override
State<MyHomePage> createState() => _MyHomePageState();
The _MyHomePageState instance is created and returned in the createState method.
This makes _MyHomePageState the state associated with MyHomePage.
In the _MyHomePageState class, the build method returns a Scaffold instance.
Scaffold Structure:
appBar→ Contains anAppBar, which displays the application title.body→ Contains aTextwidget to display a message.
This results in a screen with an app bar and a text message.
Passing Values from StatelessWidget to StatefulWidget
Here, we introduce a new process:
Passing values from the StatelessWidget (which serves as the foundation of the app) to a StatefulWidget.
In the StatelessWidget class (MyApp), the following value is prepared:
final title = 'Flutter sample';
final message = 'sample message;
The final keyword is specified, meaning the value cannot be changed.
In a StatelessWidget, we use fixed values like this.
These values are then passed to the StatefulWidget and used within it.
return MaterialApp(
title: 'Flutter Demo',
home: new MyHomePage(
title: this.title,
message: this.message
),
);
When creating an instance of MyHomePage for the home property, two values—title and message—are provided.
These values are assigned using this.title and this.message in the constructor.
In other words, the properties are passed as arguments when instantiating MyHomePage.
In the MyHomePage class, the constructor is defined as follows:
const MyHomePage({super.key, required this.title, required this.message});
In this class, the title and message properties are also defined.
The values passed as arguments are directly assigned to this.title and this.message.
This means that the values prepared in MyApp are successfully passed to MyHomePage.
Passing Data from MyHomePage to _MyHomePageState
Now, let’s see how title and message stored in MyHomePage are used inside _MyHomePageState.
When _MyHomePageState‘s build method is called, it creates a Scaffold instance to define the app’s structure.
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Text(
widget.message,
style: TextStyle(fontSize: 32.0),
)
);
In the Text widget, we specify widget.title and widget.message as arguments.
What is widget?
- So,
widget.titlerefers toMyHomePage‘stitleproperty. widgetis a property available in theStateclass.- It stores the instance of the associated
StatefulWidget(in this case,MyHomePage).
With this setup, the values stored in MyHomePage can now be used inside _MyHomePageState.
By referencing widget.title and widget.message, _MyHomePageState can access the properties of MyHomePage and use them to display content dynamically.
Handling FloatingActionButton Tap
Now that we understand the basics of StatefulWidget, let’s modify our sample to change the displayed text when the button is tapped.
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
final title = 'Flutter sample';
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
home: new MyHomePage(title: this.title),
);
}
}
class MyHomePage extends StatefulWidget {
final String title;
const MyHomePage({super.key, required this.title});
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
String _message = 'Hello';
void _setMessage() {
setState(() {
_message = 'Tapped!';
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Text(
_message,
style: TextStyle(fontSize: 32.0),
),
floatingActionButton: FloatingActionButton(
onPressed: _setMessage,
tooltip: 'set message.',
child: Icon(Icons.star),
),
);
}
}
When you run the app, it will look like the image below.

When the button is tapped, the message display changes!!

It is a very simple example, but it includes the minimum necessary elements to demonstrate state changes through user interaction.
State Update and setState
State changes should be handled within a method inside the State class.
In this case, we define a method called _setMessage to update the state.
void _setMessage() {
setState(() {
_message = 'Tapped!';
});
}
The _setMessage method calls setState, which notifies the State class that an update has occurred.
Key Points About setState
✔️ Notifies the framework that the state has changed.
✔️ Triggers the build method, updating the UI.
✔️ Accepts a function as its argument, where the state-changing logic is placed.
In this sample, the _message property is updated inside the function passed to setState.
How the Update Works
When _message changes, setState triggers a rebuild, updating the displayed text.
The _message property is modified inside setState().
Since _message is used in Text(_message), the UI depends on this value.
About FloatingActionButton
The floatingActionButton property in the Scaffold widget is used to display a floating action button (FAB). This is a round button typically placed at the bottom-right of the screen, commonly used for primary actions in an app.
The FloatingActionButton is provided as a class in Flutter, allowing the creation of a floating, circular button commonly used for primary actions in an app.
In the provided sample, floatingActionButton is set as follows:
floatingActionButton: FloatingActionButton(
onPressed: _setMessage,
tooltip: 'set message.',
child: Icon(Icons.star),
),
When creating a FloatingActionButton instance, you can provide various arguments to customize its behavior and appearance.
onPressed (Action on Tap)
- In this case,
_setMessageis assigned. - Specifies what happens when the button is tapped.
- Usually, a method is assigned to handle the action.
tooltip (Hint Text)
- Useful for providing additional information about the button’s function.
- Defines the text that appears when the user long-presses the button.
child (Content Inside the Button)
- Typically contains an icon but can also include other widgets.
- Specifies what is displayed inside the button.
When creating a FloatingActionButton instance, these properties can be specified as anonymous class elements within the widget’s constructor.
Among the various properties, the most crucial one is onPressed.
Why is onPressed Important?
- Triggers an event when the button is tapped.
- Specifies a method responsible for state changes.
- Executes an action linked to the button press.
How onPressed Works
If the widget has an onPressed property, it executes the assigned method.
When the button is tapped, an onPressed event occurs.
While onPressed is a crucial event for buttons, Flutter provides many other event handlers that respond to different user interactions.
The Icon class is used to display icons in a Flutter app.
How the Icon Class Works
- Supports color, size, and other styling options.
- Represents an icon visually.
- Requires an icon value from the
Iconsclass.
The FloatingActionButton (FAB) in Flutter requires at least two essential properties:
onPressed→ Specifies what happens when the button is tapped.child→ Defines the icon inside the button.
Using Complex Values
So far, we’ve only displayed simple text values, but StatefulWidgets can also handle more complex data structures.
Let’s define a Data class and pass its instance to a StatefulWidget.
Since the base MyApp class is exactly the same, we will omit it and only post the MyHomePage class and beyond.
class MyHomePage extends StatefulWidget {
final String title;
const MyHomePage({super.key, required this.title});
@override
State<MyHomePage> createState() => _MyHomePageState();
}
//Data Classes
class Data {
int _price;
String _name;
Data(this._name, this._price) : super();
@override
String toString() {
return _name + ':' + _price.toString() + 'yen';
}
}
class _MyHomePageState extends State<MyHomePage> {
//Sample data
static final _data = [
Data('Apple', 200),
Data('Orange', 150),
Data('Peach', 300),
];
Data _item = _data[0];
void _setData() {
setState(() {
_item = (_data..shuffle()).first;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Text(
_item.toString(),
style: TextStyle(fontSize: 32.0),
),
floatingActionButton: FloatingActionButton(
onPressed: _setData,
tooltip: 'set message.',
child: Icon(Icons.star),
),
);
}
}
Here, the _MyHomePageState class has a _data property that stores a list of Data objects. When the button is tapped, a Data object is randomly selected and displayed on the screen.

About the Data class
The Data class is defined to handle data composed of multiple values. When dealing with complex values, it is common to define and use a class that organizes the necessary information.
class Data {
int _price;
String _name;
Data(this._name, this._price) : super();
@override
String toString() {
return _name + ':' + _price.toString() + 'yen';
}
}
In the Data class, two properties, _name and _price, are defined. The constructor allows setting these properties using the provided arguments.
Additionally, the toString method is overridden to format and return the data as a text string.
Configuring the Data instance
On the state class side, a list of Data instances is prepared, and a random selection from the list is displayed.
First, a list of data items and a property to store the selected data are defined.
static final _data = [
Data('Apple', 200),
Data('Orange', 150),
Data('Peach', 300),
];
Data _item = _data[0];
The _data property, which stores Data instances, is declared as static final because its contents do not change after initialization.
Additionally, the first item of _data is assigned to _item, ensuring that the initial data is displayed when the app starts.
The only remaining step is to implement the _setData method, which randomly selects an item from the list and updates the state.
void _setData() {
setState(() {
_item = (_data..shuffle()).first;
});
}
Here, the value is retrieved using (_data..shuffle()).first inside setState.
shuffle()is a method that randomly rearranges the items in a list.firstretrieves the first item from the shuffled list.
This allows a random item to be selected from _data each time the method is called.
summary
This time, we explored StatefulWidget, which allows dynamic value changes using state!
How was it?
Watching the text on the screen update dynamically is quite interesting, isn’t it?
In the next article, we will continue with Flutter layout, referencing the official documentation.
Wishing you a great Flutter development experience! 🚀
2025-03-21
0件のコメント
コメントはまだありません。最初の一人になりましょう!