Scaffold هو ودجة هيكل مركزي في Flutter ينفذ هيكل Material Design الأساسي للشاشة مع AppBar وDrawer وBottomNavigationBar وFloatingActionButton. إنه لا يضع العناصر فحسب، بل يوفر بنية جاهزة بترتيب z صحيح ومعالجة إيماءات المستخدم. وفقًا لـ توثيق Flutter (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 فوق الواجهة بأكملها، ولكن أسفل نوافذ الحوار.
وفقًا لـ مرجع API Flutter (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 للأجهزة ذات النتوء. يمكن تضمين TabBar في AppBar لتبديل علامات التبويب باستخدام الخاصية bottom.
Drawer هو لوحة تنزلق من اليسار وتوفر التنقل عبر أقسام التطبيق. يضيف Scaffold تلقائيًا أيقونة الهامبرغر إلى AppBar إذا كانت الخاصية drawer مضبوطة. يمكن أن يحتوي Drawer على DrawerHeader وListView مع عناصر القائمة ومعلومات المستخدم.
BottomNavigationBar هو لوحة في الجزء السفلي من الشاشة للتبديل بين الأقسام الرئيسية. يحتوي على 2 إلى 5 أيقونات مع تسميات ويدعم Material 3 مع مؤشر نشط عبر NavigationBar. يضعه Scaffold في أسفل الشاشة، مع تحريك body تلقائيًا لأعلى حتى لا يتداخل المحتوى.
FloatingActionButton هو زر دائري يوضع في الزاوية اليمنى السفلية من الشاشة. يتم استخدامه للإجراء الرئيسي على الشاشة، مثل إضافة إدخال جديد أو إرسال رسالة. يدعم Scaffold عدة FABs مع حركة ممتدة من خلال الخصائص الممتدة.
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، ودعم الألوان الديناميكية عبر ColorScheme.fromSeed وتوصيات محدثة للهوامش وارتفاعات المكونات. لا يتطلب الانتقال إلى M3 استبدال Scaffold — فقط قم بتحديث قالب التطبيق.
لتمكين Material 3 في مشروع، يجب تعيين useMaterial3: true في ThemeData. يقوم Scaffold تلقائيًا بتكييف النمط البصري: تصبح الهوامش أكبر (24dp بدلاً من 16dp)، ويتم إعادة حساب الألوان من اللون الأساسي، ويحصل FloatingActionButton على أحجام أكبر بزوايا دائرية. في نفس الوقت، تظل جميع خصائص Scaffold الحالية وظيفية.
وفقًا لـ مواصفات Material Design 3 (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. سوف نقدم لك النصح ونقترح أفضل حل.