Ответ
Технически можно, но это почти всегда плохая практика. Scaffold — это каркасный виджет, который предоставляет базовую структуру Material Design-страницы: AppBar, Drawer, BottomNavigationBar, FloatingActionButton и SnackBar. Несколько Scaffold в одной иерархии создают конфликты.
Проблемы при использовании нескольких Scaffold:
- Конфликтующие
ScaffoldMessenger—SnackBarмогут показываться в непредсказуемом месте - Наложение
AppBar— несколько панелей инструментов запутают пользователя - Проблемы с навигацией —
Navigatorможет работать некорректно - Нарушение Material Design — противоречит принципам дизайна от Google
Когда это может быть оправдано (редко):
// Пример: модальный BottomSheet с собственной AppBar
void _showCustomSheet(BuildContext context) {
showModalBottomSheet(
context: context,
isScrollControlled: true,
builder: (context) => Scaffold(
appBar: AppBar(
title: Text('Детали'),
automaticallyImplyLeading: false,
actions: [
IconButton(
icon: Icon(Icons.close),
onPressed: () => Navigator.pop(context),
)
],
),
body: ListView(
children: [/* содержимое */],
),
),
);
}
Правильные альтернативы для сложных интерфейсов:
// 1. Используйте CustomScrollView с SliverAppBar
CustomScrollView(
slivers: [
SliverAppBar(/* ... */),
SliverList(/* ... */),
// Еще один SliverAppBar для секции
SliverAppBar(
pinned: true,
title: Text('Вторая секция'),
),
],
)
// 2. Вложенные Container с разными фонами
Column(
children: [
Container(
color: Theme.of(context).appBarTheme.color,
padding: EdgeInsets.all(16),
child: Row(/* псевдо-AppBar */),
),
Expanded(child: /* основное содержимое */),
],
)
В моих проектах я придерживаюсь правила: один Scaffold на один экран навигации. Для сложных макетов использую CustomScrollView, NestedScrollView или кастомные виджеты.
Ответ 18+ 🔞
А, ну это же классика, блядь! Слушай, тут народ частенько спрашивает: а можно ли запихнуть один Scaffold в другой? Технически-то можно, ёпта, компилятор не заругается. Но это будет такая же пиздопроебибна, как пытаться надеть два шлема сразу — голова вроде и защищена, но нихуя не видно и выглядишь как полный ебанько.
Вот на какие грабли ты наступишь, если начнёшь плодить Scaffold-ы:
ScaffoldMessengerнихуя не поймёт. ТвойSnackBarможет вылезти где угодно: на втором этаже, в соседнем подъезде, а пользователь будет сидеть и думать: «Чё за хуйня, где моё сообщение?».AppBarнаAppBar-е. Представь, у тебя две панели инструментов торчат одна над другой. Пользователь охуеет и просто снесёт приложение к хуям.- Навигация сломается в хлам.
Navigatorзапутается, как пьяный в трёх соснах, и начнёт ронять страницы куда попало. - Material Design в ахуе. Гугловские дизайнеры смотрят на такое и плачут. Это как прийти в театр в трусах и каске — технически ты одет, но всем похуй, ты идиот.
Хотя, блядь, есть один хитрый случай, где это не так уж и тупо:
// Допустим, тебе надо выкатить модалку снизу, но чтоб у неё была своя шапка
void _showCustomSheet(BuildContext context) {
showModalBottomSheet(
context: context,
isScrollControlled: true,
builder: (context) => Scaffold( // Второй Scaffold ТОЛЬКО внутри модалки!
appBar: AppBar(
title: Text('Детали'),
automaticallyImplyLeading: false,
actions: [
IconButton(
icon: Icon(Icons.close),
onPressed: () => Navigator.pop(context),
)
],
),
body: ListView(
children: [/* содержимое */],
),
),
);
}
Но если тебе просто хочется сложную хуйню с кучей скроллов и секций — делай по-человечески:
// 1. Кастомные скроллы — твой лучший друг
CustomScrollView(
slivers: [
SliverAppBar(/* ... */), // Первая липкая шапка
SliverList(/* ... */), // Основной контент
// И вот ещё одна секция со своей шапкой
SliverAppBar(
pinned: true,
title: Text('Вторая секция'),
),
],
)
// 2. Просто контейнеры, Карл!
Column(
children: [
Container(
color: Theme.of(context).appBarTheme.color,
padding: EdgeInsets.all(16),
child: Row(/* делаем вид, что это AppBar */),
),
Expanded(child: /* а тут уже основное тело */),
],
)
Короче, запомни, как «Отче наш»: один экран — один Scaffold. Не выёбывайся. Для всего остального есть CustomScrollView и голова на плечах, чтобы думать, а не просто впендюривать виджеты друг в друга.