MaterialApp, Scaffold и структура экрана

MaterialApp и Scaffold — это каркас, который даёт приложению тему, навигацию и стандартные зоны экрана.

Суть: MaterialApp оборачивает всё приложение, задавая тему и маршруты. Scaffold — каркас одного экрана с зонами: appBar, body, floatingActionButton, bottomNavigationBar.

Material Design — это не просто набор виджетов, а целая дизайн-система Google с правилами про отступы, тени, цвета и анимации. Flutter реализует её свежую версию, Material 3, где вся палитра приложения выводится из одного «зерна» — базового цвета через ColorScheme.fromSeed. Задав один seedColor, вы получаете согласованный набор оттенков для кнопок, фонов и текста, и приложение выглядит цельно без ручного подбора каждого цвета.

Если бы каждый экран приходилось рисовать с нуля — фон, шапку, расположение кнопок — разработка была бы мучением. Flutter даёт готовый каркас по гайдлайнам Material Design. Корень приложения — MaterialApp: он включает тему, локализацию и систему маршрутов. Внутри каждого экрана — Scaffold, который раскладывает стандартные зоны.

class HomeScreen extends StatelessWidget {
  const HomeScreen({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Главная')),
      body: const Center(child: Text('Содержимое экрана')),
      floatingActionButton: FloatingActionButton(
        onPressed: () {},
        child: const Icon(Icons.add),
      ),
      bottomNavigationBar: BottomNavigationBar(items: const [
        BottomNavigationBarItem(icon: Icon(Icons.home), label: 'Дом'),
        BottomNavigationBarItem(icon: Icon(Icons.person), label: 'Профиль'),
      ]),
    );
  }
}

Каждая именованная зона Scaffold — это слот для виджета. appBar — шапка сверху, body — основное содержимое, floatingActionButton — круглая кнопка действия, bottomNavigationBar — нижняя навигация. Заполняете нужные, пропускаете остальные.

Как устроен каркас под капотом

Scaffold сам вычисляет, сколько места занимает шапка и нижняя панель, и отдаёт оставшееся пространство body. Он же управляет наложениями: всплывающими SnackBar, выезжающим меню Drawer. MaterialApp предоставляет всем виджетам ниже доступ к теме через Theme.of(context) — поэтому цвета и шрифты единообразны.

  MaterialApp (тема, маршруты, локализация)
        |
     Scaffold
   +-----------------------------+
   |  AppBar  [ Главная ]        |  <- appBar
   +-----------------------------+
   |                             |
   |       body                  |  <- основное содержимое
   |    (Center -> Text)         |
   |                       (+)   |  <- floatingActionButton
   +-----------------------------+
   | [Дом]        [Профиль]      |  <- bottomNavigationBar
   +-----------------------------+
# Модель Scaffold: слоты экрана и сборка структуры
def scaffold(app_bar=None, body=None, fab=None, bottom_nav=None):
    parts = []
    if app_bar:    parts.append(f'[AppBar: {app_bar}]')
    if body:       parts.append(f'[Body: {body}]')
    if fab:        parts.append(f'[FAB: {fab}]')
    if bottom_nav: parts.append(f'[BottomNav: {", ".join(bottom_nav)}]')
    return '\n'.join(parts)

screen = scaffold(
    app_bar='Главная',
    body='Содержимое экрана',
    fab='+',
    bottom_nav=['Дом', 'Профиль'],
)
print(screen)

Частые ошибки

  • Забыть обернуть приложение в MaterialApp — тогда виджеты вроде Scaffold и AppBar упадут с ошибкой об отсутствии Material-предка.
  • Класть несколько Scaffold друг в друга на одном экране — обычно достаточно одного.
  • Перегружать body без прокрутки — длинный контент обрежется; нужен ListView или SingleChildScrollView.

Best practices

  • Один экран — один Scaffold; разные экраны — отдельные виджеты-классы.
  • Задавайте тему один раз в MaterialApp через ThemeData с colorScheme на основе seedColor (Material 3).
  • Используйте SafeArea, чтобы содержимое не залезало под вырезы и системные панели.

Помимо основных зон, Scaffold умеет показывать выезжающее боковое меню через свойство drawer и всплывающие уведомления через ScaffoldMessenger с его SnackBar. Эти механизмы тоже встроены и работают по гайдлайнам из коробки. Чем больше готовых возможностей каркаса вы знаете, тем меньше изобретаете велосипедов — а Material-каркас покрывает добрую половину типичных потребностей экрана.

Итог: MaterialApp задаёт тему и маршруты всему приложению, а Scaffold раскладывает один экран по понятным зонам. Освоив этот каркас, вы готовы наполнять body виджетами вёрстки — этим займётся следующий раздел.

Проверьте себя
1. Какую роль играет Scaffold во Flutter?
AЗапускает приложение
BЗадаёт глобальную тему
CДаёт каркас одного экрана с зонами: appBar, body, FAB, нижняя навигация
DХранит состояние
2. Что произойдёт, если использовать Scaffold без обёртки MaterialApp?
AНичего, всё работает
BОшибка об отсутствии Material-предка
CПриложение станет быстрее
DScaffold превратится в StatelessWidget