Scaffold — это центральный виджет-каркас во Flutter, который реализует базовую Material Design-структуру экрана с AppBar, Drawer, BottomNavigationBar и FloatingActionButton. Он не просто позиционирует элементы, а предоставляет готовую архитектуру с правильным z-порядком и обработкой пользовательских жестов. По данным Flutter Documentation (2026), Scaffold является обязательным корневым элементом для корректной работы Material-компонентов, включая SnackBar и BottomSheet. В отличие от Container или Column, Scaffold автоматически управляет SafeArea, адаптивным фоном и поведением клавиатуры, что делает его стандартом для построения экранов в мобильных приложениях.
Главное
Scaffold — это виджет-компоновщик из библиотеки Material Design, который формирует базовую визуальную структуру экрана. Он реализует стандартный паттерн приложения Material: верхняя панель, тело экрана, боковое меню и плавающие кнопки. В отличие от Container, который просто задаёт размеры и стиль, Scaffold управляет целым экраном как единой системой.
Каждое Flutter-приложение, построенное по Material Design, начинается с MaterialApp, внутри которого каждый экран оборачивается в Scaffold. Именно Scaffold обеспечивает корректное отображение AppBar на всех устройствах, учитывая SafeArea для iPhone X и выше. Он также отвечает за z-порядок: Drawer отображается поверх body, а SnackBar — поверх всего интерфейса, но ниже диалоговых окон.
По данным официального Flutter API Reference (2026), Scaffold является обязательным условием для корректной работы таких виджетов, как SnackBar, BottomSheet и PersistentBottomSheet. Без Scaffold эти компоненты выбрасывают исключение, поскольку они зависят от InheritedWidget Scaffold.of для доступа к контексту Scaffold. Поэтому размещение любого контента напрямую в Container вместо Scaffold — распространённая ошибка начинающих разработчиков, приводящая к потере Material-функциональности.
В типичном Flutter-приложении Scaffold находится внутри MaterialApp, обычно под WidgetsApp или CupertinoApp при кросс-платформенной разработке. MaterialApp создаёт Navigator и тему, а Scaffold определяет структуру текущего экрана. Каждый экран может иметь свой Scaffold с уникальными AppBar, Drawer и BottomNavigationBar, что позволяет гибко настраивать интерфейс под конкретную страницу.
Для глубокой кастомизации Scaffold можно комбинировать с NestedScrollView — это позволяет реализовать сложные скролл-эффекты, например, исчезающий AppBar с parallax-эффектом. Однако в большинстве случаев стандартного Scaffold с его свойствами достаточно для построения production-ready экрана.
Scaffold состоит из нескольких обязательных и опциональных зон, каждая из которых отвечает за определённую часть интерфейса. Рассмотрим каждую часть в отдельности, чтобы понять, как они взаимодействуют друг с другом.
AppBar — это верхняя панель экрана, которая отображает заголовок, кнопку навигации и действия. Она автоматически получает правильную высоту в 56dp и учитывает SafeArea для устройств с «чёлочкой». В AppBar можно встроить TabBar для переключения вкладок, используя свойство bottom.
Drawer — это панель, выезжающая слева и предоставляющая навигацию по разделам приложения. Scaffold автоматически добавляет иконку «гамбургер» в AppBar, если свойство drawer установлено. Drawer может содержать DrawerHeader, ListView с пунктами меню и пользовательскую информацию.
BottomNavigationBar — это панель в нижней части экрана для переключения между основными разделами. Она содержит от 2 до 5 иконок с подписями и поддерживает Material 3 с активной индикацией через NavigationBar. Scaffold позиционирует её внизу экрана, автоматически сдвигая body выше, чтобы контент не перекрывался.
FloatingActionButton — это круглая кнопка, размещаемая в правом нижнем углу экрана. Она используется для основного действия на экране, например, добавления новой записи или отправки сообщения. Scaffold поддерживает несколько FAB с расширенной анимацией через extended свойства.
Body — это центральная область экрана, в которую помещается основной контент. В качестве body может выступать любой виджет: Column, ListView, GridView, Stack или кастомная композиция. Scaffold автоматически рассчитывает высоту body с учётом AppBar, BottomNavigationBar и SafeArea, что избавляет от ручной подгонки размеров.
Scaffold предоставляет более 30 свойств для настройки внешнего вида и поведения экрана. Среди них есть как обязательные (body), так и опциональные, управляющие отступами, фоном и состоянием клавиатуры. Понимание каждого свойства помогает точно настроить интерфейс под требования дизайна.
| Свойство | Тип | Описание |
|---|---|---|
| appBar | PreferredSizeWidget? | Верхняя панель экрана с заголовком и действиями |
| body | Widget? | Основное содержимое экрана между AppBar и BottomNavigationBar |
| drawer | Widget? | Боковая панель, открывающаяся свайпом слева |
| bottomNavigationBar | Widget? | Нижняя панель навигации (BottomNavigationBar или NavigationBar) |
| floatingActionButton | Widget? | Плавающая кнопка основного действия |
| backgroundColor | Color? | Цвет фона Scaffold, переопределяющий тему |
| resizeToAvoidBottomInset | bool | Автоматическое сжатие body при появлении клавиатуры |
Свойство resizeToAvoidBottomInset особенно важно при работе с формами: когда оно установлено в true (по умолчанию), Scaffold автоматически сжимает body при появлении клавиатуры, чтобы поле ввода оставалось видимым. Это избавляет от необходимости писать кастомные слушатели клавиатуры. Для кастомных сценариев с SingleChildScrollView свойство можно отключить.
Рассмотрим практический пример Scaffold с полным набором Material-компонентов. Код создаёт экран с AppBar, Drawer, BottomNavigationBar, FloatingActionButton и SnackBar — типичная структура мобильного приложения на Flutter.
class MainScreen extends StatefulWidget {
const MainScreen({super.key});
@override
State<MainScreen> createState() => _MainScreenState();
}
class _MainScreenState extends State<MainScreen> {
int selectedIndex = 0;
final List<Widget> pages = [
const HomePage(),
const SearchPage(),
const ProfilePage(),
];
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('My App'),
actions: [
IconButton(icon: const Icon(Icons.search), onPressed: () {}),
],
),
body: pages[selectedIndex],
drawer: Drawer(
child: ListView(
children: [
const DrawerHeader(child: Text('Menu')),
ListTile(title: const Text('Settings'), onTap: () {}),
],
),
),
bottomNavigationBar: NavigationBar(
selectedIndex: selectedIndex,
onDestinationSelected: (int index) {
setState(() => selectedIndex = index);
},
destinations: const [
NavigationDestination(icon: Icon(Icons.home), label: 'Home'),
NavigationDestination(icon: Icon(Icons.search), label: 'Search'),
NavigationDestination(icon: Icon(Icons.person), label: 'Profile'),
],
),
floatingActionButton: FloatingActionButton(
onPressed: () {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('Action completed')),
);
},
child: const Icon(Icons.add),
),
);
}
}
В примере используется NavigationBar из Material 3 вместо устаревшего BottomNavigationBar. Scaffold автоматически связывает все части: при открытии Drawer SnackBar скрывается, при переключении вкладок body обновляется, а FloatingActionButton остаётся на месте. ScaffoldMessenger гарантирует показ SnackBar даже при наличии нескольких Scaffold в иерархии.
Material 3 (M3) — это эволюция Material Design, представленная Google в 2023 году. Scaffold в M3 получил ряд изменений: новый виджет NavigationBar вместо BottomNavigationBar, поддержку Dynamic Color через ColorScheme.fromSeed и обновлённые рекомендации по отступам и высоте компонентов. Переход на M3 не требует замены Scaffold — достаточно обновить тему приложения.
Для включения Material 3 в проекте необходимо установить useMaterial3: true в ThemeData. Scaffold автоматически адаптирует визуальное оформление: отступы становятся больше (24dp вместо 16dp), цвета пересчитываются из seed-цвета, а FloatingActionButton получает более крупные размеры с закруглёнными углами. При этом все существующие свойства Scaffold остаются рабочими.
По данным Material Design 3 Specification (2026), рекомендуется использовать NavigationBar с тремя-пятью пунктами вместо BottomNavigationBar. Scaffold поддерживает оба варианта, но NavigationBar предоставляет лучшую поддержку адаптивности и Material You на устройствах Pixel.
Для корректной работы Scaffold с M3 достаточно обновить тему и заменить BottomNavigationBar на NavigationBar. Цвета будут автоматически рассчитаны через ColorScheme.fromSeed, а Scaffold подстроит отступы под новые стандарты. При необходимости можно переопределить backgroundColor напрямую.
Часто задаваемые вопросы
Scaffold — это виджет-каркас целого экрана с поддержкой Material-компонентов (AppBar, Drawer, SnackBar), в то время как Container — это базовый контейнер для одного дочернего элемента без управления структурой экрана. Scaffold предоставляет z-порядок, SafeArea и автоматическую обработку жестов, а Container только задаёт размеры и стиль.
Технически да, но на практике это не рекомендуется. Если вложить один Scaffold в другой, внутренний Scaffold создаст собственный AppBar и BottomNavigationBar, что приведёт к дублированию панелей и путанице в z-порядке. Для сложных макетов используйте NestedScrollView или Column внутри body одного Scaffold.
SnackBar является дочерним компонентом Scaffold и требует его присутствия в дереве виджетов для корректного отображения. Scaffold предоставляет ScaffoldState, через который SnackBar анимирует появление и позиционируется в нижней части экрана. Без Scaffold SnackBar выбрасывает исключение, поскольку не может найти ScaffoldState в контексте через InheritedWidget.
Цвет фона Scaffold задаётся через свойство backgroundColor, которое переопределяет цвет темы для конкретного экрана. Если нужно изменить фон глобально, установите scaffoldBackgroundColor в ThemeData. Material 3 автоматически рассчитывает фоновый цвет из ColorScheme.surface, но его можно переопределить вручную.
ScaffoldMessenger — это утилита, представленная в Flutter 2.5, которая позволяет показывать SnackBar и BottomSheet независимо от текущего Scaffold в иерархии. В отличие от устаревшего Scaffold.of(context), ScaffoldMessenger работает корректно при навигации между экранами и не теряет контекст при анимациях. Рекомендуется всегда использовать ScaffoldMessenger для обратной связи.
Итоги
Мы разработаем мобильное приложение под ключ
IT Sectr создаёт приложения для iOS и Android для стартапов и бизнеса с 2017 года. Мы проконсультируем вас и предложим наилучшее решение.
Читайте также