Understanding Widgets as the Building Blocks of Flutter UI
Widgets are the fundamental building blocks used to create user interfaces in Flutter.
Almost every visible or structural part of a Flutter application is represented using a widget.
Text, buttons, images, layouts, padding, navigation structures, themes, and even many invisible
layout helpers are created by composing widgets together.
Flutter follows a declarative and reactive UI approach. Instead of manually changing individual
UI elements, developers describe what the interface should look like for a particular state, and
Flutter efficiently updates the UI when the state changes.
Learn more about Flutter through the
JustAcademy Flutter Training Course
.
You can also use the
Register for Course Demo
to explore the training program.
1. What Is a Widget?
A widget is an immutable description of a part of the user interface. It tells Flutter what
should appear on the screen and how different parts of the interface should be arranged.
In simple words:
A Flutter widget is a reusable building block that describes part of the application's UI.
For example, the following elements can all be represented using widgets:
- Text
- Images
- Icons
- Buttons
- Text fields
- Cards
- Rows and columns
- Padding and spacing
- App bars
- Navigation components
- Dialogs
- Lists and grids
- Animations
- Themes
2. Why Are Widgets Important in Flutter?
Flutter uses widgets as the primary unit of UI composition. Rather than having separate systems
for different UI concepts, Flutter allows developers to combine small widgets to create complex
interfaces.
Main advantages of widgets
- Reusable: A widget can be reused in multiple parts of an application.
- Composable: Small widgets can be combined to create complex UI components.
- Customizable: Developers can configure widgets through properties.
- Maintainable: Large interfaces can be divided into smaller components.
- Reactive: Widgets can rebuild when application state changes.
- Cross-platform: The same Flutter widget-based code can target multiple platforms.
3. The "Everything Is a Widget" Concept
One of the most important concepts for a Flutter beginner is that Flutter uses widgets for much
more than just visible UI elements.
For example:
Text displays text.
Icon displays an icon.
Image displays images.
Container helps with layout and decoration.
Padding adds space around a child.
Center centers a child.
Row arranges widgets horizontally.
Column arranges widgets vertically.
Expanded controls how available space is distributed.
Scaffold provides a common Material page structure.
This consistent widget-based architecture makes Flutter UI development highly compositional.
4. Understanding Widget Composition
Widget composition means creating a larger UI component by combining smaller widgets.
Instead of creating one huge component containing all UI logic, Flutter encourages developers
to combine smaller, focused widgets.
Example
Column(
children: [
const Text('Student Profile'),
const SizedBox(height: 10),
const Icon(Icons.person),
ElevatedButton(
onPressed: () {},
child: const Text('View Profile'),
),
],
)
In this example, Column contains multiple child widgets:
Text
SizedBox
Icon
ElevatedButton
This demonstrates how several small widgets can be composed to create a complete UI section.
5. Widget Tree
Flutter represents the UI as a hierarchy of widgets called the widget tree.
A widget can contain another widget as its child, and a parent widget can contain multiple
child widgets.
Example Widget Tree
MaterialApp
└── Scaffold
├── AppBar
│ └── Text
└── Center
└── Column
├── Icon
├── Text
└── ElevatedButton
└── Text
The tree structure makes it possible for Flutter to understand relationships between different
parts of the UI.
Simple Example
MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('My App'),
),
body: Center(
child: const Text('Hello Flutter'),
),
),
)
Here, MaterialApp is the parent of Scaffold, while
Scaffold contains the AppBar and Center widgets.
6. Parent and Child Widgets
Flutter widgets are commonly connected through parent-child relationships.
A parent widget controls or contains one or more child widgets.
Single Child Example
Center(
child: Text('Hello Flutter'),
)
Here:
Center is the parent widget.
Text is the child widget.
Multiple Children Example
Column(
children: [
Text('Name'),
Text('Email'),
Text('Phone'),
],
)
Here, Column is the parent and the three Text widgets are its children.
7. The child and children Properties
Flutter widgets commonly use either child or children.
child
The child property is used when a widget accepts one child.
Center(
child: Text('Hello'),
)
children
The children property is used when a widget can contain multiple children.
Column(
children: [
Text('One'),
Text('Two'),
Text('Three'),
],
)
| Property |
Purpose |
Example |
| child |
Accepts one widget |
Center, Padding, Container |
| children |
Accepts multiple widgets |
Row, Column, Stack |
8. Common Flutter Widgets
| Widget |
Purpose |
Example |
| Text |
Displays text |
Text('Hello') |
| Icon |
Displays an icon |
Icon(Icons.home) |
| Image |
Displays images |
Image.asset('image.png') |
| Container |
Provides layout and decoration |
Container() |
| Row |
Arranges children horizontally |
Row(children: []) |
| Column |
Arranges children vertically |
Column(children: []) |
| Center |
Centers a child |
Center(child: ...) |
| Padding |
Adds space around a widget |
Padding(...) |
| SizedBox |
Creates fixed spacing or size |
SizedBox(height: 20) |
| Expanded |
Uses available space inside Row/Column/Flex |
Expanded(child: ...) |
| Card |
Creates Material-style card UI |
Card(child: ...) |
| ListView |
Creates a scrollable list |
ListView(children: []) |
| Scaffold |
Provides common Material page structure |
Scaffold(...) |
9. Text Widget
The Text widget is used to display text in a Flutter application.
Text(
'Welcome to Flutter',
)
Styled Text
Text(
'Welcome to Flutter',
style: TextStyle(
fontSize: 24,
fontWeight: FontWeight.bold,
),
)
The TextStyle object can control properties such as font size, weight, letter
spacing, decoration, and other text presentation options.
10. Container Widget
Container is commonly used when you need to combine layout, sizing, padding,
margin, alignment, and decoration around a child.
Container(
width: 200,
height: 100,
padding: const EdgeInsets.all(16),
alignment: Alignment.center,
decoration: BoxDecoration(
color: Colors.blue,
borderRadius: BorderRadius.circular(12),
),
child: const Text(
'Flutter',
style: TextStyle(
color: Colors.white,
fontSize: 20,
),
),
)
11. Row Widget
Row places its children horizontally.
Row(
children: [
Icon(Icons.home),
SizedBox(width: 10),
Text('Home'),
],
)
Using Main Axis Alignment
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text('Product'),
Text('₹999'),
],
)
12. Column Widget
Column places its children vertically.
Column(
children: [
Text('Student Name'),
Text('Manish'),
ElevatedButton(
onPressed: () {},
child: Text('View Profile'),
),
],
)
13. Center Widget
The Center widget positions its child in the center of the available space.
Center(
child: Text('Centered Text'),
)
14. Padding Widget
Padding adds empty space around its child.
Padding(
padding: const EdgeInsets.all(20),
child: Text('Padded Content'),
)
Different Padding Values
Padding(
padding: const EdgeInsets.symmetric(
horizontal: 20,
vertical: 10,
),
child: Text('Responsive spacing'),
)
15. SizedBox Widget
SizedBox is frequently used for fixed dimensions and spacing.
Column(
children: [
Text('First'),
SizedBox(height: 20),
Text('Second'),
],
)
16. Expanded Widget
Expanded allows a child of a Row, Column, or
Flex to occupy available space.
Row(
children: [
Expanded(
child: Container(
height: 50,
color: Colors.blue,
),
),
Expanded(
child: Container(
height: 50,
color: Colors.green,
),
),
],
)
Multiple Expanded widgets can divide the available space using their
flex values.
Row(
children: [
Expanded(
flex: 2,
child: Container(height: 50),
),
Expanded(
flex: 1,
child: Container(height: 50),
),
],
)
17. Scaffold Widget
Scaffold provides a common structure for Material-style application screens.
Scaffold(
appBar: AppBar(
title: const Text('My App'),
),
body: const Center(
child: Text('Welcome'),
),
)
Common areas provided by Scaffold include:
appBar
body
drawer
floatingActionButton
bottomNavigationBar
bottomSheet
18. StatelessWidget
A StatelessWidget is appropriate when the widget's configuration does not need
mutable state managed by that widget.
class WelcomeMessage extends StatelessWidget {
const WelcomeMessage({super.key});
@override
Widget build(BuildContext context) {
return const Text(
'Welcome to Flutter!',
);
}
}
Using the Custom Widget
Column(
children: const [
WelcomeMessage(),
Text('Learn Flutter'),
],
)
Creating custom widgets helps make applications easier to read, reuse, test, and maintain.
19. StatefulWidget
A StatefulWidget is used when part of the UI needs mutable state that can change
during the lifetime of the widget.
Counter Example
class CounterWidget extends StatefulWidget {
const CounterWidget({super.key});
@override
State createState() => _CounterWidgetState();
}
class _CounterWidgetState extends State {
int count = 0;
void incrementCounter() {
setState(() {
count++;
});
}
@override
Widget build(BuildContext context) {
return Column(
children: [
Text('Count: $count'),
ElevatedButton(
onPressed: incrementCounter,
child: const Text('Increment'),
),
],
);
}
}
When setState() is called, Flutter knows that the state has changed and can rebuild
the relevant part of the interface.
20. StatelessWidget vs StatefulWidget
| Feature |
StatelessWidget |
StatefulWidget |
| Mutable state |
Not managed by the widget itself |
Can manage mutable state through a State object |
| State class |
Not required |
Required |
| Common use |
Static or configuration-driven UI |
Interactive or changing UI |
| Rebuild trigger |
Usually caused by parent/configuration changes |
setState() can request a rebuild of its state subtree |
21. Widget Properties
Widgets are configured using properties passed through their constructors.
Container(
width: 200,
height: 100,
color: Colors.blue,
)
In this example:
width controls the width.
height controls the height.
color specifies the container's color.
Properties allow the same widget type to be configured differently in different locations.
22. Widgets Are Immutable
Flutter widgets are immutable descriptions of UI configuration. You generally do not modify
the fields of an existing widget instance. Instead, Flutter can receive a new widget
configuration and efficiently reconcile it with the existing UI structure.
For stateful components, mutable state is stored separately in the associated
State object.
Important Concept
Widget Configuration
↓
build()
↓
Widget Tree
↓
Flutter Framework
↓
Rendered UI
23. The build() Method
The build() method describes the UI that a widget wants Flutter to display.
class MyWidget extends StatelessWidget {
const MyWidget({super.key});
@override
Widget build(BuildContext context) {
return const Text('Hello Flutter');
}
}
The method returns another widget, which may itself contain more widgets.
A good build() method should primarily describe UI and should avoid expensive or
unrelated side effects.
24. Reactive UI and Widgets
Flutter follows a reactive UI model. The application state influences the UI, and when relevant
state changes, Flutter can rebuild the affected widgets.
Application State
↓
build()
↓
Widget Tree
↓
UI Update
Example
int count = 10;
Text(
'Current count: $count',
)
If the state changes and the relevant widget rebuilds, the displayed value can also change.
25. Widgets for Layout
Some widgets primarily control how other widgets are positioned and sized.
| Widget |
Purpose |
| Row |
Horizontal layout |
| Column |
Vertical layout |
| Stack |
Places widgets on top of each other |
| Expanded |
Expands a child within Flex layout |
| Flexible |
Allows flexible space allocation |
| Center |
Centers a child |
| Align |
Positions a child within available space |
| Padding |
Adds space around a child |
| ConstrainedBox |
Applies additional constraints |
26. Interactive Widgets
Flutter provides many widgets that respond to user interaction.
Button Example
ElevatedButton(
onPressed: () {
print('Button clicked');
},
child: const Text('Click Me'),
)
TextField Example
TextField(
decoration: InputDecoration(
labelText: 'Enter your name',
border: OutlineInputBorder(),
),
)
Checkbox Example
Checkbox(
value: true,
onChanged: (value) {
print(value);
},
)
27. GestureDetector
GestureDetector can be used to detect various gestures performed by the user.
GestureDetector(
onTap: () {
print('Container tapped');
},
child: Container(
padding: const EdgeInsets.all(20),
color: Colors.blue,
child: const Text(
'Tap Me',
style: TextStyle(color: Colors.white),
),
),
)
28. ListView as a Widget
ListView is commonly used for displaying scrollable content.
ListView(
children: const [
ListTile(
leading: Icon(Icons.person),
title: Text('John'),
),
ListTile(
leading: Icon(Icons.person),
title: Text('Sarah'),
),
ListTile(
leading: Icon(Icons.person),
title: Text('Alex'),
),
],
)
ListView.builder
ListView.builder is useful when list items are generated dynamically.
ListView.builder(
itemCount: 20,
itemBuilder: (context, index) {
return ListTile(
title: Text('Item ${index + 1}'),
);
},
)
29. Creating Your Own Reusable Widget
One of the most useful skills in Flutter is learning how to create custom widgets.
Student Card Example
class StudentCard extends StatelessWidget {
final String name;
final String course;
const StudentCard({
super.key,
required this.name,
required this.course,
});
@override
Widget build(BuildContext context) {
return Card(
child: Padding(
padding: const EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
name,
style: const TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
),
),
const SizedBox(height: 8),
Text(course),
],
),
),
);
}
}
Using the Reusable Widget
Column(
children: const [
StudentCard(
name: 'Rahul',
course: 'Flutter Development',
),
StudentCard(
name: 'Priya',
course: 'Dart Programming',
),
],
)
The same StudentCard widget can now be reused with different data.
30. Widget Reusability
Reusability is one of the biggest advantages of the widget-based approach.
Instead of repeating the same UI code, you can create a custom widget and use it multiple times.
Without Reusable Widget
Container(
padding: const EdgeInsets.all(16),
child: Text('Product 1'),
)
Container(
padding: const EdgeInsets.all(16),
child: Text('Product 2'),
)
With Reusable Widget
ProductCard(title: 'Product 1'),
ProductCard(title: 'Product 2'),
ProductCard(title: 'Product 3'),
This approach reduces duplication and makes UI changes easier.
31. Widget Composition Example
A real application screen may be composed of many layers of widgets.
MaterialApp
└── Scaffold
├── AppBar
│ └── Text
└── Padding
└── Column
├── CircleAvatar
├── SizedBox
├── Text
├── Text
├── Row
│ ├── Icon
│ └── Text
└── ElevatedButton
└── Text
This demonstrates an important Flutter principle: complex screens can be constructed by
composing many small widgets.
32. Complete Practical Example
The following example creates a simple Flutter profile screen using multiple widgets.
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: const ProfilePage(),
);
}
}
class ProfilePage extends StatelessWidget {
const ProfilePage({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Student Profile'),
),
body: Center(
child: Padding(
padding: const EdgeInsets.all(20),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const CircleAvatar(
radius: 50,
child: Icon(
Icons.person,
size: 50,
),
),
const SizedBox(height: 20),
const Text(
'Manish',
style: TextStyle(
fontSize: 24,
fontWeight: FontWeight.bold,
),
),
const SizedBox(height: 8),
const Text(
'Flutter Developer',
style: TextStyle(
fontSize: 16,
),
),
const SizedBox(height: 20),
ElevatedButton(
onPressed: () {
print('Profile button clicked');
},
child: const Text('View Profile'),
),
],
),
),
),
);
}
}
Widgets Used in This Example
| Widget |
Purpose |
| MaterialApp |
Root Material application widget |
| Scaffold |
Provides the basic screen structure |
| AppBar |
Displays the application bar |
| Center |
Centers the content |
| Padding |
Adds spacing around the content |
| Column |
Arranges content vertically |
| CircleAvatar |
Displays a circular profile area |
| Icon |
Displays the profile icon |
| Text |
Displays profile information |
| SizedBox |
Creates vertical spacing |
| ElevatedButton |
Provides an interactive button |
33. Understanding Widget Rebuilding
Flutter does not require developers to manually update every UI element after a state change.
When relevant state changes, Flutter can call the appropriate build methods and reconcile the
resulting widget configuration with the existing UI.
State Changes
↓
setState() / State Update
↓
Relevant build() method
↓
New Widget Configuration
↓
Flutter compares the UI structure
↓
Required UI updates are rendered
This is one reason the declarative approach can make interactive UI easier to reason about.
34. Widget Tree vs Element Tree vs Render Tree
Beginners usually work directly with widgets, but Flutter internally uses additional structures
to manage the UI efficiently.
Widget Tree
The widget tree contains immutable widget configurations describing the desired UI.
Element Tree
Elements connect widget configurations to their position in the active UI structure and help
Flutter preserve identity and state when appropriate.
Render Tree
Render objects are responsible for layout, painting, hit testing, and related rendering work.
Widget Tree
↓
Element Tree
↓
Render Tree
↓
Pixels on Screen
Understanding these layers is not required for writing your first Flutter application, but it
becomes useful when learning Flutter's rendering and performance model.
35. Material and Cupertino Widgets
Flutter includes widget libraries for different design systems.
Material Widgets
Material widgets provide components following Google's Material design system.
MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('Material App'),
),
body: const Center(
child: Text('Hello'),
),
),
)
Cupertino Widgets
Cupertino widgets provide controls and visual patterns designed around Apple's platform
design language.
CupertinoApp(
home: CupertinoPageScaffold(
navigationBar: const CupertinoNavigationBar(
middle: Text('iOS Style'),
),
child: const Center(
child: Text('Hello'),
),
),
)
36. Widget Categories
Flutter provides a large collection of widgets that can be grouped according to their purpose.
| Category |
Examples |
| Basic UI |
Text, Icon, Image |
| Layout |
Row, Column, Stack, Wrap |
| Spacing |
Padding, SizedBox |
| Input |
TextField, Checkbox, Switch |
| Interaction |
GestureDetector, buttons |
| Scrolling |
ListView, GridView, CustomScrollView |
| Material |
Scaffold, AppBar, Card, Dialog |
| Animation |
AnimatedContainer, AnimatedOpacity |
| Styling |
Theme, DecoratedBox, Container |
37. Important Widget Concepts for Beginners
- Flutter UI is built using widgets.
- Widgets are immutable descriptions of UI configuration.
- Widgets can contain other widgets.
- Widgets form a hierarchical widget tree.
child is generally used for a single child.
children is generally used for multiple children.
StatelessWidget is used for widgets without mutable state managed by that widget.
StatefulWidget is used when mutable state is required.
- The
build() method describes the widget's UI.
- Widgets can be composed to create complex screens.
- Custom widgets improve code organization and reusability.
- Flutter can efficiently update relevant portions of the UI when state changes.
38. Best Practices for Working with Widgets
1. Keep Widgets Small
Avoid creating extremely large widget classes. Break complex screens into meaningful reusable
widgets.
2. Use Meaningful Names
ProfileHeader()
ProductCard()
LoginForm()
NavigationBar()
StudentDetails()
3. Reuse Common UI
If the same UI appears multiple times, consider creating a reusable custom widget.
4. Keep build() Focused
The build() method should primarily describe the UI. Avoid expensive computations
and unrelated side effects inside it.
5. Use const Where Appropriate
const Text('Hello Flutter')
Using const where a widget and its configuration are compile-time constants can
help communicate that the widget is not expected to change.
6. Avoid Unnecessary Nesting
Use widgets because they provide a useful layout, behavior, styling, or abstraction. Avoid
adding unnecessary layers when they do not provide value.
39. Common Beginner Mistakes
Mistake 1: Putting Everything in One Widget
Large screens become difficult to understand when every part of the UI is placed inside one
enormous build() method.
Better approach: Divide the UI into meaningful custom widgets.
Mistake 2: Confusing child and children
// One child
Center(
child: Text('Hello'),
)
// Multiple children
Column(
children: [
Text('One'),
Text('Two'),
],
)
Mistake 3: Forgetting setState()
When changing mutable state inside a State object, the UI may not update as
expected unless the change is properly communicated to Flutter, commonly through
setState() for local state.
Mistake 4: Performing Heavy Work in build()
Since build methods may be called repeatedly, expensive operations should not unnecessarily
be performed inside them.
40. Practical Exercise
Create a Flutter screen called Student Profile using the following widgets:
Scaffold
AppBar
CircleAvatar
Text
Column
Row
Icon
SizedBox
Card
ElevatedButton
Suggested UI
Student Profile
-------------------------
Profile Icon
Manish Negi
Flutter Developer
📧 Email
📱 Phone
📍 Location
[ View Profile ]
Try to create separate custom widgets such as ProfileHeader,
ContactRow, and ProfileButton.
41. Interview Questions
- What is a widget in Flutter?
- Why are widgets called the building blocks of Flutter UI?
- What is widget composition?
- What is a widget tree?
- What is the difference between
child and children?
- What is a
StatelessWidget?
- What is a
StatefulWidget?
- What is the purpose of the
build() method?
- Why are Flutter widgets immutable?
- What is the purpose of
setState()?
- How do you create a reusable custom widget?
- What is the difference between a widget tree and a render tree?
- Why should expensive operations generally be avoided inside
build()?
- What is widget composition?
- How do Material and Cupertino widgets differ?
42. Quick Revision
| Concept |
Meaning |
| Widget |
Immutable description of part of the UI |
| Widget Tree |
Hierarchy of widgets forming the UI structure |
| Composition |
Combining smaller widgets to create larger UI components |
| StatelessWidget |
Widget without mutable state managed by the widget itself |
| StatefulWidget |
Widget whose associated State can change over time |
| build() |
Describes the widget's UI |
| child |
Single child widget |
| children |
Multiple child widgets |
| setState() |
Signals that local State has changed and the UI should be rebuilt |
| Custom Widget |
Developer-created reusable widget |
43. Key Takeaways
- Widgets are the fundamental building blocks of Flutter UI.
- Flutter applications are constructed by composing widgets.
- Widgets form a hierarchical widget tree.
- Widgets can represent visible UI as well as layout and behavioral structure.
- Small widgets can be combined to create complex screens.
StatelessWidget is useful when the widget itself does not manage mutable state.
StatefulWidget works with a separate State object for mutable state.
- The
build() method describes the UI for the current configuration/state.
- Reusable custom widgets make applications easier to maintain.
- Understanding widget composition is essential for becoming comfortable with Flutter.
44. Learning Resources
For structured Flutter learning, explore the
JustAcademy Flutter Training Course
.
To register for a course demonstration, visit:
JustAcademy Course Demo Registration
.
For official Flutter documentation, visit:
Flutter Widget Catalog
.
You can also study the
Flutter Architectural Overview
to understand widgets, composition, state, and the rendering architecture in greater depth.
Conclusion
Widgets are at the heart of Flutter UI development. A Flutter application is created by
composing widgets into a hierarchical widget tree. Simple widgets such as Text,
Icon, and Image can be combined with layout widgets such as
Row, Column, Stack, and Padding to create
sophisticated interfaces.
Once you understand how widgets work, how they are composed, how the widget tree is structured,
and how state affects rebuilding, you have a strong foundation for learning more advanced
Flutter concepts such as navigation, forms, animations, state management, responsive layouts,
APIs, and complete application architecture.