Flutter Lesson 22 of 83 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”.