Flutter Scaffold Explained: AppBar, Body, Drawer, and FAB

Coding Liquids blog cover featuring Sagnik Bhattacharya for the Flutter Scaffold guide, with AppBar, body, Drawer, FloatingActionButton, and bottom navigation slot visuals.
Coding Liquids blog cover featuring Sagnik Bhattacharya for the Flutter Scaffold guide.

Almost every Material screen you build starts with a Scaffold. It's the frame that holds the app bar, the body, a floating action button, side drawers, and a bottom navigation bar, and arranges them all correctly — including the fiddly job of keeping your content above the keyboard. Understand its slots once and screen structure stops being guesswork. This guide covers each slot, SnackBars the modern way, drawers, FAB placement, and the keyboard inset, with paste-ready code.

The Complete Flutter Guide course thumbnail

The Complete Flutter Guide: Build Android, iOS and Web apps

Go from scratch to building industry-standard apps with Riverpod, Firebase, animations, REST APIs, and more.

Enrol now

Every snippet below is paste-ready against current stable Flutter. The Scaffold's biggest slot is the AppBar, which has a guide of its own; here we focus on the frame as a whole and how its pieces fit together.

Follow me on Instagram@sagnikteaches

We'll set up a basic Scaffold, look at the body and floating action button, add a drawer, show a SnackBar through ScaffoldMessenger, and cover the keyboard inset behaviour.

Connect on LinkedInSagnik Bhattacharya

If you'd rather watch a full screen come together slot by slot, the channel builds Scaffold-based screens end to end in real projects.

Subscribe on YouTube@codingliquids

The Scaffold skeleton

A typical screen sets the appBar and body slots, and often a floatingActionButton. The Scaffold positions each correctly and gives the body the space that's left.

Scaffold(
  appBar: AppBar(title: const Text('Inbox')),
  body: const Center(child: Text('Your messages appear here')),
  floatingActionButton: FloatingActionButton(
    onPressed: () {},
    child: const Icon(Icons.add),
  ),
)

The body takes a single widget, which is usually a ListView, a Column, or a Center. Everything else is optional furniture the Scaffold knows how to place — you opt into each slot as the screen needs it.

The floating action button

FloatingActionButton is the prominent circular action that hovers over the body — compose, add, create. Use FloatingActionButton.extended when you want a label beside the icon, and floatingActionButtonLocation to move it.

Scaffold(
  floatingActionButton: FloatingActionButton.extended(
    onPressed: () {},
    icon: const Icon(Icons.edit),
    label: const Text('Compose'),
  ),
  floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat,
  body: const SizedBox.expand(),
)

Reserve the FAB for the screen's single primary action; if everything is a FAB, nothing is. The Scaffold handles its elevation, position, and the way it shifts up when a SnackBar appears.

SnackBars the modern way

To show a transient message, use ScaffoldMessenger — not the old Scaffold.of(context). ScaffoldMessenger owns SnackBars, which is why they persist across route changes and don't fail on the build context.

ScaffoldMessenger.of(context).showSnackBar(
  const SnackBar(content: Text('Message sent')),
);

This is the source of a classic beginner error: calling Scaffold.of(context) with the same context that built the Scaffold throws, because that context can't find a Scaffold ancestor. ScaffoldMessenger.of(context) sidesteps the problem entirely and is the current, recommended API.

The Complete Flutter Guide course thumbnail

Structure every screen with confidence

The Complete Flutter Guide covers Scaffold, navigation, and app structure from first principles through to shipped apps.

Enrol now

Drawers

Pass a Drawer to the drawer slot and the Scaffold does the rest: it adds a hamburger button to the AppBar, wires up the edge-swipe gesture, and handles the slide animation.

Scaffold(
  appBar: AppBar(title: const Text('Home')),
  drawer: Drawer(
    child: ListView(
      children: const [
        DrawerHeader(child: Text('Menu')),
        ListTile(leading: Icon(Icons.settings), title: Text('Settings')),
      ],
    ),
  ),
  body: const SizedBox.expand(),
)

Use endDrawer for a panel that slides in from the opposite edge — handy for filters or a secondary menu. Inside the drawer, a ListView of ListTiles is the standard content.

The keyboard inset

By default the Scaffold sets resizeToAvoidBottomInset: true, so when the keyboard appears the body shrinks to stay above it and your text fields remain visible. Set it to false when you specifically want content to stay put and slide under the keyboard — for example a full-bleed background that shouldn't jump.

Scaffold(
  resizeToAvoidBottomInset: false, // body ignores the keyboard
  body: const DecoratedBox(decoration: BoxDecoration(/* full-bleed */)),
)

Common mistakes

  • Using Scaffold.of(context) for SnackBars. Use ScaffoldMessenger.of(context), which owns them and avoids the context error.
  • Nesting Scaffolds without reason. Generally one Scaffold per screen; extra ones cause duplicate app bars and odd insets.
  • Putting an unbounded body in a Column. The body fills available space; an inner scrollable usually needs Expanded — see the Expanded guide.
  • Overusing the FAB. Reserve it for the one primary action per screen.
  • Forgetting the keyboard inset. Leave resizeToAvoidBottomInset on for forms; turn it off only deliberately.

Frequently asked questions

What is a Scaffold in Flutter?

The top-level Material screen layout with slots for appBar, body, floatingActionButton, drawer, and bottomNavigationBar. One Scaffold per screen is typical.

How do I show a SnackBar in Flutter?

ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text('...'))). ScaffoldMessenger owns SnackBars in current Flutter.

How do I add a navigation drawer in Flutter?

Pass a Drawer to the Scaffold's drawer slot; the hamburger button and swipe gesture are added automatically. Use endDrawer for the other side.

What does resizeToAvoidBottomInset do in Flutter?

When true (default), the body resizes to stay above the keyboard. Set it false to let content slide under the keyboard instead.

Further reads

Keep going with the tutorials that pair with this guide:

Sources: Flutter documentation — Scaffold, ScaffoldMessenger, SnackBar, Drawer, FloatingActionButton, and FloatingActionButtonLocation API references, plus the Material 3 layout guidance (docs.flutter.dev). Verified against current stable Flutter.