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 این کامپوننتها استثنا ایجاد میکنند، زیرا برای دسترسی به زمینه Scaffold به InheritedWidget Scaffold.of وابسته هستند. بنابراین قرار دادن هر محتوایی مستقیماً در Container به جای Scaffold یک اشتباه رایج برنامهنویسان مبتدی است که به از دست رفتن کارکرد Material منجر میشود.
در یک برنامه Flutter معمولی، Scaffold در داخل MaterialApp، معمولاً زیر WidgetsApp یا CupertinoApp در توسعه چندسطحی قرار میگیرد. MaterialApp Navigator و پوسته را ایجاد میکند، و Scaffold ساختار صفحه جاری را مشخص میکند. هر صفحه میتواند Scaffold خود را با AppBar، Drawer و BottomNavigationBar منحصر به فرد داشته باشد، که امکان تنظیم انعطافپذیر رابط را برای یک صفحه خاص فراهم میکند.
برای سفارشی سازی عمیق، Scaffold را میتوان با NestedScrollView ترکیب کرد — این امکان پیاده سازی افکتهای پیچیده پیمایش را همچون AppBar ناپدید شونده با افکت پارالاکس فراهم میکند. اما در اکثر موارد، Scaffold استاندارد با ویژگیهایش برای ساخت یک صفحه آماده تولید کافی است.
Scaffold از چند منطقه اجباری و اختیاری تشکیل شده است که هر کدام مسئول بخش خاصی از رابط هستند. بیایید هر بخش را جداگانه بررسی کنیم تا بفهمیم چگونه با یکدیگر تعامل میکنند.
AppBar — پانل بالایی صفحه است که عنوان، دکمه ناوبری و اقدامات را نمایش میدهد. آن به طور خودکار ارتفاع صحیح 56dp را دریافت میکند و SafeArea را برای دستگاههای دارای بریدگی در نظر میگیرد. برای تغییر زبانهها میتوان TabBar را با استفاده از ویژگی bottom در AppBar جاسازی کرد.
Drawer — پانلی است که از سمت چپ خارج شده و ناوبری را در بخشهای برنامه فراهم میکند. اگر ویژگی drawer تنظیم شده باشد، Scaffold به طور خودکار آیکون هامبرگر را به AppBar اضافه میکند. 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),
),
);
}
}
در نمونه به جای BottomNavigationBar کهنه از NavigationBar از Material 3 استفاده شده است. 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)، رنگها از رنگ دانه محاسبه میشوند، و 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 از سال 2017 برنامههای iOS و Android را برای استارتاپها و کسبوکارها ایجاد میکند. ما به شما مشاوره میدهیم و بهترین راهحل را پیشنهاد خواهیم کرد.
همچنین بخوانید