Dart Tutorial

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'),
          ],
        ),
      ),
    ),
  );
}
SlotHolds
appBarThe bar at the top
bodyThe main content
floatingActionButtonThe primary action of the screen
bottomNavigationBarNavigation between top-level sections
drawer, endDrawerSide menus
bottomSheetA persistent panel at the bottom
backgroundColorPage background

AppBar #

PropertyPurpose
titleUsually a Text
leadingWidget before the title. A back button appears here automatically when there is a page to go back to
actionsWidgets after the title, usually IconButtons
bottomA widget under the bar, usually a TabBar
centerTitleCentre the title
backgroundColor, foregroundColorColours
elevation, scrolledUnderElevationShadow

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”.

Practise in the playground Updated by Santosh Adhikari