Everything is a Widget
In Flutter, everything is a widget. A button is a widget. A text label is a widget. A whole screen is a widget made of smaller widgets. Think of widgets like LEGO bricks — you snap them together to build your interface. The beauty is in the composition.
There are two main types of widgets: StatelessWidget (doesn't change once built) and StatefulWidget (can change over time). Most of the widgets you'll use are from the Material or Cupertino library, but you can always create your own custom widgets.
import 'package:flutter/material.dart';
void main() {
runApp(
MaterialApp(
home: Scaffold(
appBar: AppBar(title: Text('Widget World')),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text('This is a Text widget'),
Icon(Icons.star, color: Colors.amber, size: 48),
ElevatedButton(
onPressed: () {},
child: Text('Click Me'),
),
],
),
),
),
),
);
}
Try it Yourself →
The Widget Tree
Widgets build a tree structure. Your app is the root widget, containing screens, which contain rows, columns, buttons, and text. This tree is what Flutter renders on screen. When something changes, Flutter rebuilds only the widgets that need updating — it's very efficient.
// A widget tree example
MaterialApp // Root
└── Scaffold // Layout
├── AppBar // Top bar
│ └── Text // Title
└── Body // Main content
└── Column // Vertical layout
├── Text // First item
├── Image // Second item
└── Button // Third item
Understanding the widget tree is key to mastering Flutter. Every widget can contain other widgets, creating a nested structure that describes your entire UI. The deeper you nest, the more complex your interface becomes.
Common Widgets
Flutter comes with a rich set of built-in widgets. Here are some you'll use all the time. Text displays strings. Image shows pictures. Container is a versatile box that can have padding, margins, colors, and borders. Row and Column arrange children horizontally and vertically.
Container(
padding: EdgeInsets.all(16),
margin: EdgeInsets.symmetric(horizontal: 20),
decoration: BoxDecoration(
color: Colors.blue,
borderRadius: BorderRadius.circular(12),
),
child: Column(
children: [
Text(
'Welcome!',
style: TextStyle(
fontSize: 24,
color: Colors.white,
fontWeight: FontWeight.bold,
),
),
SizedBox(height: 10),
Text('This is a styled container'),
],
),
)
Try it Yourself →
Composing Widgets
The real power of Flutter comes from composing widgets inside other widgets. A Container might hold a Column, which holds Text and Image widgets. This nesting creates your entire UI. Don't be afraid to build deep widget trees — Flutter is designed for this.
Card(
elevation: 4,
margin: EdgeInsets.all(16),
child: Padding(
padding: EdgeInsets.all(16),
child: Row(
children: [
CircleAvatar(
radius: 30,
backgroundColor: Colors.blue,
child: Text('A', style: TextStyle(fontSize: 24)),
),
SizedBox(width: 16),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('Alice Johnson', style: TextStyle(fontSize: 18)),
Text('Software Developer', style: TextStyle(color: Colors.grey)),
],
),
),
Icon(Icons.arrow_forward_ios, color: Colors.grey),
],
),
),
)
This creates a nice card with an avatar, name, and title. By combining simple widgets, you build complex, beautiful interfaces. That's the Flutter way.
Try it Yourself →