MaterialApp & Scaffold
The Foundation Every Flutter App Stands On
Open interactive version (quiz + challenge)Real-world analogy
What is it?
MaterialApp is the root widget that initializes Material Design services for your Flutter app: theming, navigation, localization, and more. Scaffold is a layout widget that implements the basic Material Design visual structure for individual screens. Together, they form the skeleton of nearly every Flutter app. MaterialApp is set up once, while Scaffold is used on each screen to provide consistent structure with an app bar, body content, floating action button, drawers, and bottom navigation.
Real-world relevance
In team_mvp_kit, MaterialApp is configured at the root of the app with go_router for declarative navigation, a global ThemeData for consistent styling, and localization delegates. Each screen returns a Scaffold with an appropriate AppBar and body. The project uses MaterialApp.router instead of the basic MaterialApp to integrate with go_router's routing system. Themes are defined in a separate theme file and passed to MaterialApp, making it easy to switch between light and dark modes.
Key points
- MaterialApp: The Root Widget — MaterialApp is typically the root of your app. It provides Material Design theming, navigation (Navigator or Router), localization, and other framework services. Most apps have exactly one MaterialApp.
- ThemeData: Global Styling — ThemeData configures colors, typography, shape, and component styles for your entire app. Define it once in MaterialApp and access it anywhere with Theme.of(context). Material 3 uses colorSchemeSeed for automatic palette generation.
- Dark Mode Support — MaterialApp accepts both theme (light) and darkTheme. Set themeMode to system, light, or dark. The app automatically switches based on the device setting when set to system.
- Scaffold: Screen Structure — Scaffold provides the visual structure for a single screen: app bar at the top, body in the middle, bottom navigation, floating action button, drawers, and snackbars. Almost every screen in a Flutter app uses Scaffold.
- AppBar: The Top Bar — AppBar displays a title, navigation icons, and action buttons at the top of the screen. It automatically includes a back button when navigation stack has entries. Customize with leading, title, and actions parameters.
- Body: The Main Content — The body parameter takes any widget and fills the remaining space between the app bar and bottom navigation. Use SingleChildScrollView to make content scrollable, or ListView for long lists.
- FloatingActionButton (FAB) — A circular button that hovers over the content. Typically used for the primary action on a screen (add, compose, create). Position it with floatingActionButtonLocation.
- BottomNavigationBar — A bar at the bottom of the screen for switching between top-level views. Each item has an icon and label. Use currentIndex to highlight the active tab and onTap to handle tab changes.
- Drawer: Side Navigation — A panel that slides in from the left (or right in RTL) for app navigation. Add a drawer parameter to Scaffold. It automatically adds a hamburger menu icon to the AppBar.
Code example
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(
title: 'Team MVP Kit',
debugShowCheckedModeBanner: false,
theme: ThemeData(
colorSchemeSeed: Colors.indigo,
useMaterial3: true,
brightness: Brightness.light,
),
darkTheme: ThemeData(
colorSchemeSeed: Colors.indigo,
useMaterial3: true,
brightness: Brightness.dark,
),
themeMode: ThemeMode.system,
home: const HomeScreen(),
);
}
}
class HomeScreen extends StatelessWidget {
const HomeScreen({super.key});
@override
Widget build(BuildContext context) {
final theme = Theme.of(context);
return Scaffold(
appBar: AppBar(
title: const Text('Home'),
actions: [
IconButton(
icon: const Icon(Icons.notifications_outlined),
onPressed: () {},
),
],
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(
Icons.rocket_launch,
size: 64,
color: theme.colorScheme.primary,
),
const SizedBox(height: 16),
Text(
'Welcome to Team MVP Kit',
style: theme.textTheme.headlineSmall,
),
const SizedBox(height: 8),
Text(
'Your app foundation is ready',
style: theme.textTheme.bodyLarge?.copyWith(
color: theme.colorScheme.onSurfaceVariant,
),
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: () {},
child: const Icon(Icons.add),
),
);
}
}Line-by-line walkthrough
- 1. Import Flutter material library
- 2. main function calls runApp with our root widget
- 3. Define MyApp as a StatelessWidget -- the root of the app
- 4. Build method returns MaterialApp -- the foundation of everything
- 5. Set title for task switcher and web page title
- 6. Disable the debug banner for a cleaner look
- 7. Define light theme with indigo color scheme and Material 3
- 8. Define dark theme with the same color seed but dark brightness
- 9. Set themeMode to system to follow device preference
- 10. Set HomeScreen as the initial route
- 11. Define HomeScreen as a StatelessWidget
- 12. Get the current theme for styling
- 13. Return Scaffold -- the structural frame for this screen
- 14. AppBar with title Text and a notification icon button in actions
- 15. Body is a centered Column with main content
- 16. A rocket icon sized 64 using the theme's primary color
- 17. SizedBox for 16px vertical spacing
- 18. Headline text styled with headlineSmall from the theme
- 19. Another SizedBox for 8px spacing
- 20. Subtitle text with bodyLarge style in a variant color
- 21. FloatingActionButton with an add icon for the primary screen action
Spot the bug
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('My App')),
body: Center(child: Text('Hello')),
);
}
}Need a hint?
Show answer
Explain like I'm 5
Fun fact
Hands-on challenge
More resources
- MaterialApp Class (api.flutter.dev)
- Scaffold Class (api.flutter.dev)
- Material Design in Flutter (docs.flutter.dev)