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 с паралакс ефект. Но в повечето случаи стандартният Scaffold с неговите свойства е достатъчен за изграждане на екран, готов за производство.
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('Моето приложение'),
actions: [
IconButton(icon: const Icon(Icons.search), onPressed: () {}),
],
),
body: pages[selectedIndex],
drawer: Drawer(
child: ListView(
children: [
const DrawerHeader(child: Text('Меню')),
ListTile(title: const Text('Настройки'), 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('Действието приключи')),
);
},
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 г. Ще ви консултираме и ще предложим най-доброто решение.
Прочетете също