← Назад к вопросам

Где применяется Scaffold?

1.3 Junior🔥 51 комментариев
#Flutter виджеты

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI23 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Scaffold в Flutter: применение и лучшие практики

Scaffold — это один из самых используемых widgets в Flutter Material Design. Это контейнер, который реализует базовую визуальную структуру Material приложения.

Что такое Scaffold и зачем он нужен

Scaffold предоставляет инфраструктуру для Material Design компонентов:

Scaffold(
  appBar: AppBar(title: Text('Home')),
  body: Center(child: Text('Content')),
  floatingActionButton: FloatingActionButton(
    onPressed: () {},
    child: Icon(Icons.add),
  ),
  drawer: Drawer(),
  bottomNavigationBar: BottomNavigationBar(),
)

Основные свойства

AppBar — верхняя панель приложения:

  • Заголовок страницы
  • Иконки действий
  • Кнопка "назад" (автоматически)
  • Состояние приложения (батарея, время, сигнал)

Body — основное содержимое:

  • Главной контент экрана
  • Всегда занимает оставшееся пространство
  • Может быть любым widget'ом

FloatingActionButton — кнопка действия:

  • Плавающая кнопка внизу справа
  • Primary action для экрана
  • Используется для главного действия (add, compose, call)

Drawer — боковое меню:

  • Material Design навигация
  • Свайп слева направо или тап иконки
  • Список меню пунктов

BottomNavigationBar — навигация снизу:

  • Переключение между основными секциями
  • Макс 5 пунктов (best practice)
  • Показывает активный tab

Практические примеры

Пример 1: Простой экран с AppBar и FloatingActionButton

class HomePage extends StatefulWidget {
  @override
  State<HomePage> createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  int _counter = 0;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Counter App'),
        elevation: 0,
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Text('Clicks:'),
            Text(
              '$_counter',
              style: Theme.of(context).textTheme.headlineMedium,
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () => setState(() => _counter++),
        child: Icon(Icons.add),
      ),
    );
  }
}

Пример 2: Scaffold с Drawer навигацией

class AppShell extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('My App'),
        // Иконка гамбургера автоматически добавляется если есть drawer
      ),
      drawer: Drawer(
        child: ListView(
          padding: EdgeInsets.zero,
          children: [
            DrawerHeader(
              decoration: BoxDecoration(color: Colors.blue),
              child: Text('Menu', style: TextStyle(color: Colors.white)),
            ),
            ListTile(
              leading: Icon(Icons.home),
              title: Text('Home'),
              onTap: () => Navigator.pop(context),
            ),
            ListTile(
              leading: Icon(Icons.settings),
              title: Text('Settings'),
              onTap: () {
                Navigator.pop(context);
                Navigator.pushNamed(context, '/settings');
              },
            ),
          ],
        ),
      ),
      body: Center(child: Text('Home page')),
    );
  }
}

Пример 3: Scaffold с BottomNavigationBar

class MainApp extends StatefulWidget {
  @override
  State<MainApp> createState() => _MainAppState();
}

class _MainAppState extends State<MainApp> {
  int _selectedIndex = 0;

  final List<Widget> _pages = [
    HomePage(),
    SearchPage(),
    ProfilePage(),
  ];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Navigation Example'),
      ),
      body: _pages[_selectedIndex],
      bottomNavigationBar: BottomNavigationBar(
        items: const [
          BottomNavigationBarItem(
            icon: Icon(Icons.home),
            label: 'Home',
          ),
          BottomNavigationBarItem(
            icon: Icon(Icons.search),
            label: 'Search',
          ),
          BottomNavigationBarItem(
            icon: Icon(Icons.person),
            label: 'Profile',
          ),
        ],
        currentIndex: _selectedIndex,
        onTap: (index) => setState(() => _selectedIndex = index),
      ),
    );
  }
}

Когда использовать Scaffold

Используй Scaffold когда:

  • Нужна стандартная Material Design структура
  • Нужна AppBar с заголовком
  • Нужна навигация (Drawer, BottomNavigationBar)
  • Нужно отобразить SnackBar или Dialog
  • Нужна FloatingActionButton
// Scaffold автоматически:
// - Добавляет padding под AppBar
// - Добавляет padding под BottomNavigationBar
// - Позиционирует FloatingActionButton
// - Показывает SnackBar с правильной позицией

НЕ используй Scaffold когда:

  • Создаешь кастомный дизайн (не Material Design)
  • Работаешь с Cupertino (iOS) стилем
  • Нужна полная кастомизация макета
  • Создаешь component library

Практические советы

1. Используй resizeToAvoidBottomInset для клавиатуры

Scaffold(
  resizeToAvoidBottomInset: true, // По умолчанию true
  body: SingleChildScrollView(
    child: Column(
      children: [
        TextField(), // Не будет скрыта клавиатурой
      ],
    ),
  ),
)

2. FloatingActionButton лучше делать в одного экрана

// ❌ Плохо: FloatingActionButton на каждый экран
if (_selectedIndex == 0) {
  floatingActionButton: FloatingActionButton(...);
}

// ✅ Хорошо: FAB только где нужен
floatingActionButton: _selectedIndex == 0 
  ? FloatingActionButton(...) 
  : null,

3. Используй SafeArea для notch'ей и bottom insets

Scaffold(
  body: SafeArea(
    child: Text('Safe from notches'),
  ),
  // Или используй viewInsets и viewPadding
)

Когда НЕ использовать Scaffold

Пример: Чистый страничный экран

// ❌ Неправильно
Scaffold(
  appBar: SizedBox.shrink(), // Пустая AppBar
  body: FullScreenImage(),
)

// ✅ Правильно
Stack(
  children: [
    FullScreenImage(),
    Positioned(
      top: 0,
      left: 0,
      child: BackButton(),
    ),
  ],
)

Scaffold — это solid choice для 90% Material Design экранов. Он обеспечивает правильное поведение, отступы, и интеграцию с Material компонентами. Знание его свойств делает UI разработку в Flutter быстрой и предсказуемой.