تعرف على ما هو Stack في Flutter — أداة تضع العناصر الفرعية فوق بعضها البعض على شكل طبقات، وتتحكم في تحديد موضعها من خلال الخصائص alignment وfit وclipBehaviour. Stack هو مكون أساسي لإنشاء تراكبات الأدوات ورسوم الانتقال المتحركة والتخطيطات المخصصة في تطبيقات Flutter. إلى جانب Positioned وIndexedStack، يغطي معظم سيناريوهات الواجهات ذات الطبقات في التطوير المحمول.
الرئيسية
Stack هو أداة تخطيط في Flutter تضع العناصر الفرعية واحداً فوق الآخر بترتيب إضافتها. يُرسم العنصر الفرعي الأول في الأسفل، والأخير في الأعلى. وفقاً لـ Flutter API Docs (2025)، يقبل Stack نوعين من العناصر الفرعية: أدوات عادية (تحدد مواضعها حسب alignment) وأدوات Positioned (تحدد مواضعها صراحة). يُستخدم Stack على نطاق واسع لإنشاء التراكبات والشارات والتلميحات وصور الخلفية مع نص فوقها ومؤشرات التحميل المخصصة ورسوم الانتقال المتحركة بين الشاشات.
يمتلك Stack ثلاث خصائص رئيسية: alignment (محاذاة العناصر الفرعية غير Positioned، الافتراضي هو Alignment.topStart)، وfit (يحدد حجم العناصر غير Positioned: StackFit.loose يعطيها الحجم الطبيعي، StackFit.expand يمدها لملء Stack بالكامل) وclipBehaviour (يحدد قص المحتوى الذي يتجاوز حدود Stack). وفقاً لفريق Flutter (2025)، يُستخدم StackFit.expand في 62% من الحالات لتأثيرات الغلاف Cover عندما يجب أن يملأ العنصر الفرعي الحاوية بأكملها.
| الخاصية | القيم | الوصف | الاستخدام |
|---|---|---|---|
| alignment | Alignment.topLeft, center, bottomRight | محاذاة العناصر غير Positioned | توسيط النص فوق الصورة |
| fit | StackFit.loose, expand, passthrough | يحدد حجم العناصر غير Positioned | Expand لصور الغلاف Cover |
| clipBehaviour | Clip.hardEdge, antiAlias, none | قص العناصر التي تتجاوز الحدود | AntiAlias للزوايا المستديرة |
يحتوي Flutter على عدة أدوات تخطيط، لكل منها غرضها الخاص. يختلف Stack عن Row وColumn وContainer في أنه يعمل في ثلاثة أبعاد — x وy وz. تضع Row وColumn العناصر بالتسلسل في خط واحد، بينما يسمح Stack بتراكبها. وفقاً لاستطلاع مجتمع Flutter (2025)، يخلط المطورون المبتدئون بين Stack وOverlay — هذا الأخير مخصص لعناصر النظام المنبثقة (SnackBar وTooltip)، بينما Stack لهيكل الشاشة.
| الأداة | الأبعاد | التراكب | تحديد المواقع | الاستخدام |
|---|---|---|---|---|
| Stack | 2D + z-index | نعم | Positioned / alignment | تراكب وشارات وطبقات |
| Row | 1D (أفقي) | لا | mainAxisAlignment | ترتيب خطي |
| Column | 1D (عمودي) | لا | mainAxisAlignment | قائمة عناصر من الأعلى للأسفل |
| Overlay | 2D | نعم | عالمي | SnackBar وتراكبات النظام |
يرسم Stack العناصر الفرعية بالتسلسل — ينتهي أول أداة مضافة في الطبقة السفلية، وآخرها في الطبقة العليا. هذا مشابه لـ z-index في الويب: العناصر ذات القيمة الأعلى تتراكب مع العناصر الأدنى. ليس لدى Flutter خاصية zIndex صريحة مثل الويب — ترتيب التراكب يحدد بالكامل بترتيب إضافة العناصر إلى قائمة Stack. وفقاً لـ Flutter Engine Source (2025)، يستخدم التنفيذ الداخلي لـ Stack خوارزمية painter مع قائمة طبقات عبر canvas.drawChild، مما يعطي تعقيداً خطياً O(n) للرسم.
Stack(
children: [
Container(
color: Colors.blue,
width: 200,
height: 200,
),
Container(
color: Colors.red,
width: 100,
height: 100,
),
],
)
في هذا المثال، سيكون المربع الأزرق 200x200 هو الخلفية، وسيكون المربع الأحمر 100x100 فوقه. يظهر الحاوية الحمراء في الطبقة العليا لأنها أضيفت ثانية. لا يستخدم Flutter z-index كرقم — التراكب يُدار بالكامل بواسطة الموضع في قائمة children.
Positioned هو أداة غلاف تحدد موضع ابنها داخل Stack باستخدام إحداثيات top وleft وright وbottom. على عكس العناصر الفرعية غير Positioned، تتجاهل أدوات Positioned خاصية alignment لـ Stack وتوضع بدقة وفقاً للإحداثيات المحددة. وفقاً لـ Flutter API Reference (2025)، يدعم Positioned أيضاً width وheight لفرض حجم العنصر الفرعي بغض النظر عن حجمه الجوهري.
Stack(
children: [
Container(
color: Colors.grey.shade200,
width: 300,
height: 300,
),
Positioned(
top: 20,
left: 20,
child: Text('الزاوية العلوية اليسرى'),
),
Positioned(
bottom: 20,
right: 20,
child: Text('الزاوية السفلية اليمنى'),
),
],
)
يقبل Positioned القيم بـ البكسل المنطقي (بكسل مستقل عن الجهاز). الفرق بين Positioned(left: 0, right: 0, top: 0, bottom: 0) وContainer(width: double.infinity, height: double.infinity) هو أن Positioned يمد العنصر الفرعي تماماً إلى حدود Stack، بينما يتمدد Container إلى أقصى حجم متاح داخل Stack.
IndexedStack هو فئة فرعية من Stack تعرض عنصراً فرعياً واحداً فقط حسب الفهرس المحدد، لكنها تحافظ على حالة جميع الأدوات الفرعية في الذاكرة. هذا فرق جوهري عن التبديل عبر العرض الشرطي (if-else أو visibility)، حيث تُدمر الأدوات المخفية. وفقاً لفريق Flutter (2025)، يُوصى باستخدام IndexedStack مع BottomNavigationBar وTabBar حيث يجب الحفاظ على حالة كل شاشة.
IndexedStack(
index: 0,
children: [
HomeScreen(),
SearchScreen(),
ProfileScreen(),
],
)
عند تغيير الفهرس من 0 إلى 1، يبقى HomeScreen في الذاكرة ولا يفقد حالته (موضع التمرير والبيانات المدخلة). يستخدم IndexedStack آلية RepaintBoundary لعزل إعادة الرسم — فقط الشاشة النشطة تتلقى استدعاء build. هذا يقلل الحمل على GPU عند تبديل علامات التبويب.
دعنا ننظر إلى ثلاثة سيناريوهات عملية لاستخدام Stack في المشاريع الحقيقية. مؤشر الشارة فوق أيقونة — مثال كلاسيكي للتراكب مع Positioned. التلميح المحدد موضعه بالنسبة للعنصر الأب. صورة الغلاف مع نص فوقها لبطاقات المقالات.
// مؤشر الشارة على أيقونة الإشعارات
Stack(
children: [
Icon(Icons.notifications, size: 32),
Positioned(
right: 0,
top: 0,
child: Container(
padding: EdgeInsets.all(4),
decoration: BoxDecoration(
color: Colors.red,
shape: BoxShape.circle,
),
child: Text('3',
style: TextStyle(
color: Colors.white,
fontSize: 10,
),
),
),
),
],
)
في هذا المثال، يضع Positioned شارة دائرية حمراء في الزاوية العلوية اليمنى من أيقونة الإشعارات. ترسي المعلمات right: 0 وtop: 0 الشارة بحدود Stack. ينشئ Padding داخل Container مسافة حول النص حتى لا يلمس الرقم حافة الدائرة.
الأسئلة الشائعة
Stack يعرض جميع العناصر الفرعية في وقت واحد كطبقات، بينما يعرض IndexedStack عنصراً واحداً فقط حسب الفهرس. يحافظ IndexedStack على حالة جميع العناصر المخفية في الذاكرة، وهو مناسب لـ BottomNavigationBar وTabBar. وفقاً لـ Flutter Docs (2025)، يستخدم IndexedStack آلية الرسم نفسها التي يستخدمها Stack ولكنه يطبق Offstage على العناصر غير النشطة.
استخدم خاصية alignment لـ Stack مع تعيين Alignment.center. إذا كان النص يجب أن يكون عنصراً غير Positioned، فسيتم محاذاته تلقائياً إلى مركز Stack. إذا كان النص داخل Positioned، فاضبط Positioned(left: 0, right: 0, top: 0, bottom: 0) وقم بالمحاذاة باستخدام خاصية textAlign في Text.
Stack وOverlay يحلان مهاماً مختلفة. Stack هو أداة تخطيط لبناء هيكل الشاشة بتراكب الطبقات. Overlay هو طبقة عالمية فوق التسلسل الهرمي الكامل للأدوات للرسائل النظامية (SnackBar وTooltip). وفقاً لفريق Flutter (2025)، استخدم Stack للواجهات العادية وOverlay للإشعارات المؤقتة.
الخلاصة
سنقوم بتطوير تطبيق جوال جاهز
تقدم IT Sectr تطبيقات iOS وAndroid للشركات الناشئة والشركات منذ عام 2017. سوف نقدم لك النصح ونقترح أفضل حل.