Flutter Beginner Lesson 23 of 135 3 min read
Scaffold and AppBar in Flutter
Learn Scaffold and AppBar in Flutter: page structure, titles, action buttons, floating action buttons and bottom bars.
On this page
MaterialApp sets up the app. Scaffold sets up one screen. Nearly every page you build starts with a Scaffold.
The slots of a Scaffold
import 'package:flutter/material.dart';
void main() {
runApp(
MaterialApp(
theme: ThemeData(colorScheme: ColorScheme.fromSeed(seedColor: Colors.teal)),
home: Scaffold(
appBar: AppBar(
title: const Text('Inbox'),
actions: [
IconButton(onPressed: () {}, icon: const Icon(Icons.search), tooltip: 'Search'),
IconButton(onPressed: () {}, icon: const Icon(Icons.more_vert), tooltip: 'More'),
],
),
body: const Center(child: Text('Your messages appear here')),
floatingActionButton: FloatingActionButton.extended(
onPressed: () {},
icon: const Icon(Icons.edit),
label: const Text('Compose'),
),
bottomNavigationBar: NavigationBar(
destinations: const [
NavigationDestination(icon: Icon(Icons.inbox), label: 'Inbox'),
NavigationDestination(icon: Icon(Icons.send), label: 'Sent'),
NavigationDestination(icon: Icon(Icons.person), label: 'Profile'),
],
),
),
),
);
}
| Slot | Holds |
|---|---|
appBar | The bar at the top |
body | The main content |
floatingActionButton | The primary action of the screen |
bottomNavigationBar | Navigation between top-level sections |
drawer, endDrawer | Side menus |
bottomSheet | A persistent panel at the bottom |
backgroundColor | Page background |
AppBar
| Property | Purpose |
|---|---|
title | Usually a Text |
leading | Widget before the title. A back button appears here automatically when there is a page to go back to |
actions | Widgets after the title, usually IconButtons |
bottom | A widget under the bar, usually a TabBar |
centerTitle | Centre the title |
backgroundColor, foregroundColor | Colours |
elevation, scrolledUnderElevation | Shadow |
Keep actions to two or three. Put the rest in an overflow menu:
PopupMenuButton<String>(
onSelected: (value) => debugPrint(value),
itemBuilder: (context) => const [
PopupMenuItem(value: 'settings', child: Text('Settings')),
PopupMenuItem(value: 'help', child: Text('Help')),
PopupMenuItem(value: 'logout', child: Text('Log out')),
],
)
FloatingActionButton
One per screen, for the single most important action.
FloatingActionButton(onPressed: _add, child: const Icon(Icons.add))
FloatingActionButton.small(onPressed: _add, child: const Icon(Icons.add))
FloatingActionButton.extended(onPressed: _add, icon: const Icon(Icons.add), label: const Text('New'))
Change its position with floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat.
The body and the keyboard
When the keyboard opens, the scaffold shrinks the body so content stays visible. A non-scrolling body then overflows. Make it scrollable (a ListView or SingleChildScrollView), which is the right fix. Setting resizeToAvoidBottomInset: false stops the resize but lets the keyboard cover your fields.
Buttons pinned to the bottom
Scaffold(
appBar: AppBar(title: const Text('Checkout')),
body: ListView(children: const [/* order summary */]),
bottomNavigationBar: SafeArea(
child: Padding(
padding: const EdgeInsets.all(16),
child: FilledButton(onPressed: () {}, child: const Text('Pay Rs. 1,499')),
),
),
)
bottomNavigationBar accepts any widget, not only a navigation bar.
Scaffold inside pages
Each page pushed with the navigator normally has its own Scaffold and AppBar. Do not nest one scaffold inside the body of another unless you have a specific reason, such as tabs with their own floating buttons.
Try it yourself
Build a notes screen: an app bar titled “Notes” with a search action and an overflow menu, a body showing “No notes yet” in the centre, and an extended floating button labelled “New note”.