Introduction
Flutter is a modern UI toolkit for building natively compiled apps across mobile, web, and desktop. In this tutorial, we’ll cover some of the most fundamental Flutter building blocks: StatelessWidget
, StatefulWidget
, MaterialApp
, Scaffold
, and super.key
. Then, we’ll move on to more advanced concepts.
1. StatelessWidget — Fixed UI Components
StatelessWidget
is used when your widget’s UI doesn’t change dynamically after it’s rendered.
import 'package:flutter/material.dart';
class MyStaticText extends StatelessWidget {
const MyStaticText({super.key});
@override
Widget build(BuildContext context) {
return Text('I am static and do not change!');
}
}
When to use:
Displaying fixed texts, logos, buttons (without interactivity).
2. MaterialApp — Starting Point of Your App
Every Flutter app usually begins with a MaterialApp
.
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'My Flutter App',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.teal),
),
home: const HomeScreen(),
);
}
}
Key Features:
- Sets global
theme
. - Defines
home
screen. - Provides routing and localization.
3. super.key — Widget Identity
super.key
is used to pass the key
from child to the parent widget class. It helps Flutter detect changes and reuse widgets efficiently.
class MyWidget extends StatelessWidget {
const MyWidget({super.key});
}
It is best practice to always include super.key
in constructors.
4. StatefulWidget — For Dynamic & Interactive UI
Use StatefulWidget
when the UI needs to change over time—like when clicking a button or toggling a switch.
class CounterWidget extends StatefulWidget {
const CounterWidget({super.key});
@override
State<CounterWidget> createState() => _CounterWidgetState();
}
class _CounterWidgetState extends State<CounterWidget> {
int counter = 0;
void increment() {
setState(() {
counter++;
});
}
@override
Widget build(BuildContext context) {
return Column(
children: [
Text('Counter: $counter'),
ElevatedButton(
onPressed: increment,
child: const Text('Increment'),
),
],
);
}
}
5. Scaffold — Your App Layout Container
Scaffold
provides a default app layout structure. It includes:
BottomNavigationBar
AppBar
Body
Drawer
FloatingActionButton
Scaffold(
appBar: AppBar(title: const Text("My App")),
body: const Center(child: Text("Hello, Flutter!")),
floatingActionButton: FloatingActionButton(
onPressed: () {},
child: const Icon(Icons.add),
),
);
Going Beyond: Advanced Widget Concepts
Widget Lifecycle
Understand the lifecycle methods:
initState()
dispose()
didUpdateWidget()
Keys (GlobalKey vs LocalKey)
Used to preserve widget state when widgets are reordered or recreated.
Navigation and Routing
Use Navigator.push()
and named routes for multi-screen apps.
Provider & State Management
Use Provider
, Riverpod
, or Bloc
for large-scale app state management.
Theme Customization
Use ThemeData
and Theme.of(context)
to build reusable and beautiful apps.
Conclusion
You’ve now learned:
- The difference between Stateless and Stateful widgets.
- How MaterialApp and Scaffold provide structure.
- The importance of
super.key
for performance and rebuilds. - How to extend these basics with advanced concepts.