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
homescreen. - 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.keyfor performance and rebuilds. - How to extend these basics with advanced concepts.