The Scaffold widget is one of the most important widgets in Flutter that provides a framework which implements the basic material design visual layout structure. When developing Flutter applications, Scaffold serves as a crucial building block for creating screens with standard Android/iOS app features.
A Flutter Scaffold widget provides a framework that comprises of drawers, snack bars, and bottom sheets in the Flutter application. It acts as a structural layout for the major material design components. The primary purpose of Scaffold is to arrange the visible elements on the screen, making it one of the most frequently used widgets in Flutter development.
The following are the constructor and properties of the Flutter Scaffold Widget class.
const Scaffold({
Key key,
this.appBar,
this.body,
this.floatingActionButton,
this.floatingActionButtonLocation,
this.persistentFooterButtons,
this.drawer,
this.endDrawer,
this.bottomNavigationBar,
this.bottomSheet,
this.floatingActionButtonAnimator,
this.backgroundColor,
this.resizeToAvoidBottomPadding = true,
this.primary = true,
})
The Scaffold widget in Flutter comes with several pre-built components that can be easily customized according to your application needs:
The AppBar is typically displayed at the top of the screen and includes a toolbar along with potentially other widgets such as TabBar and FlexibleSpaceBar. It provides dedicated space for displaying the screen title, navigation options, and action buttons.
appBar: AppBar(
title: Text('Scaffold Example'),
actions: [
IconButton(
icon: Icon(Icons.search),
onPressed: () {},
),
],
)
The body parameter represents the primary content of the Scaffold. It occupies most of the available screen space between the AppBar and BottomNavigationBar (if present).
body: Center(
child: Text('This is the body of Scaffold'),
)
The FloatingActionButton is a circular icon button that floats over the UI, typically in the bottom right corner. It's used for promoting a primary action in the application.
floatingActionButton: FloatingActionButton(
onPressed: () {},
child: Icon(Icons.add),
)
A Drawer is a panel that slides in horizontally from the edge of a Scaffold to show navigation links in your application. It's commonly used to provide access to different sections of your app.
drawer: Drawer(
child: ListView(
children: [
DrawerHeader(
child: Text('Drawer Header'),
decoration: BoxDecoration(
color: Colors.blue,
),
),
ListTile(
title: Text('Item 1'),
onTap: () {},
),
],
),
)
The BottomNavigationBar is a horizontal bar displayed at the bottom of the Scaffold. It typically contains multiple items with icons and optional text labels.
bottomNavigationBar: BottomNavigationBar(
items: [
BottomNavigationBarItem(
icon: Icon(Icons.home),
label: 'Home',
),
BottomNavigationBarItem(
icon: Icon(Icons.business),
label: 'Business',
),
],
currentIndex: 0,
onTap: (index) {},
)
A BottomSheet is a sheet of material that slides up from the bottom edge of the Scaffold. There are two types of bottom sheets: persistent and modal.
The backgroundColor property allows you to set the background color of the Scaffold.
backgroundColor: Colors.lightBlue[50]
A SnackBar is a lightweight message with an optional action that briefly displays at the bottom of the screen. It's typically used to provide feedback about an operation.
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text('This is a SnackBar!'),
action: SnackBarAction(
label: 'Undo',
onPressed: () {},
),
),
);
Here's a basic implementation of a Scaffold widget in Flutter:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Flutter Scaffold Example'),
),
body: Center(
child: Text('Welcome to Flutter Scaffold!'),
),
floatingActionButton: FloatingActionButton(
onPressed: () {},
child: Icon(Icons.add),
),
),
);
}
}
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _selectedIndex = 0;
static const List<Widget> _widgetOptions = <Widget>[
Text('Home Page'),
Text('Business Page'),
Text('Settings Page'),
];
void _onItemTapped(int index) {
setState(() {
_selectedIndex = index;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Scaffold with Navigation'),
),
drawer: Drawer(
child: ListView(
padding: EdgeInsets.zero,
children: <Widget>[
DrawerHeader(
decoration: BoxDecoration(
color: Colors.blue,
),
child: Text('Drawer Header'),
),
ListTile(
title: Text('Item 1'),
onTap: () {
Navigator.pop(context);
},
),
ListTile(
title: Text('Item 2'),
onTap: () {
Navigator.pop(context);
},
),
],
),
),
body: Center(
child: _widgetOptions.elementAt(_selectedIndex),
),
bottomNavigationBar: BottomNavigationBar(
items: const <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: Icon(Icons.home),
label: 'Home',
),
BottomNavigationBarItem(
icon: Icon(Icons.business),
label: 'Business',
),
BottomNavigationBarItem(
icon: Icon(Icons.settings),
label: 'Settings',
),
],
currentIndex: _selectedIndex,
selectedItemColor: Colors.amber[800],
onTap: _onItemTapped,
),
);
}
}
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: SnackBarPage(),
);
}
}
class SnackBarPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Scaffold with SnackBar'),
),
body: Center(
child: ElevatedButton(
onPressed: () {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text('This is a SnackBar!'),
action: SnackBarAction(
label: 'Undo',
onPressed: () {},
),
),
);
},
child: Text('Show SnackBar'),
),
),
);
}
}
The Scaffold widget allows you to customize the position of the FloatingActionButton through the floatingActionButtonLocation
property:
Scaffold(
floatingActionButton: FloatingActionButton(
onPressed: () {},
child: Icon(Icons.add),
),
floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
)
There are several predefined positions available:
FloatingActionButtonLocation.endFloat
(default)FloatingActionButtonLocation.centerFloat
FloatingActionButtonLocation.endDocked
FloatingActionButtonLocation.centerDocked
To display a persistent bottom sheet using Scaffold:
Scaffold.of(context).showBottomSheet(
(BuildContext context) {
return Container(
height: 200,
color: Colors.amber,
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Text('Persistent Bottom Sheet'),
ElevatedButton(
child: Text('Close'),
onPressed: () {
Navigator.pop(context);
},
)
],
),
),
);
},
);
To display a modal bottom sheet:
showModalBottomSheet(
context: context,
builder: (BuildContext context) {
return Container(
height: 200,
color: Colors.blue,
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Text('Modal Bottom Sheet'),
ElevatedButton(
child: Text('Close'),
onPressed: () {
Navigator.pop(context);
},
)
],
),
),
);
},
);
In addition to the regular drawer, Scaffold also provides an endDrawer
parameter for a drawer on the right side (or left side in right-to-left languages):
Scaffold(
endDrawer: Drawer(
child: ListView(
children: [
DrawerHeader(
child: Text('End Drawer Header'),
decoration: BoxDecoration(
color: Colors.green,
),
),
ListTile(
title: Text('Item 1'),
onTap: () {},
),
],
),
),
)
Here's a comprehensive list of the most commonly used properties in the Scaffold widget:
appBar
: Displays an AppBar at the top of the Scaffold.body
: The primary content of the Scaffold.floatingActionButton
: A button displayed floating above the body, in the bottom right corner.floatingActionButtonLocation
: Where to place the floating action button.floatingActionButtonAnimator
: Animator for the floating action button.persistentFooterButtons
: A set of buttons that are displayed at the bottom of the Scaffold.drawer
: A panel displayed to the side of the body, often hidden on mobile devices.endDrawer
: A panel displayed to the right side of the body.bottomNavigationBar
: A navigation bar displayed at the bottom of the Scaffold.bottomSheet
: A persistent bottom sheet displayed below the body.backgroundColor
: The color of the Material widget that underlies the entire Scaffold.resizeToAvoidBottomInset
: Whether the body should resize when the keyboard appears.primary
: Whether this scaffold is being displayed at the top of the screen.drawerScrimColor
: The color to use for the scrim that obscures the primary content when a drawer is open.extendBody
: Whether the body should extend behind the bottomNavigationBar.extendBodyBehindAppBar
: Whether the body should extend behind the AppBar.drawerEdgeDragWidth
: The width of the area within which a horizontal drag will open the drawer.drawerEnableOpenDragGesture
: Whether the drawer can be opened with a drag gesture.endDrawerEnableOpenDragGesture
: Whether the end drawer can be opened with a drag gesture.