Expanded هو عنصر واجهة (widget) في Flutter يُجبر العنصر الفرعي على ملء كل المساحة المتاحة في حاوية Flex. عندما يقوم Row أو Column بتوزيع المساحة بين العناصر الفرعية، يأخذ Expanded المساحة الحرة بعد حساب العناصر غير المرنة. وفقًا للتوثيق الرسمي لـ Flutter (2026)، يُعد Expanded أحد أكثر عناصر التخطيط استخدامًا: فهو يُطبق في الواجهات النسبية المئوية، بناء البطاقات، القوائم واللوحات. ميزته الرئيسية هي الحساب التلقائي للعرض أو الارتفاع بناءً على معامل flex دون تحديد الأبعاد بشكل صريح.
النقاط الرئيسية
Expanded هو عنصر غلاف (wrapper widget) يأخذ عنصرًا فرعيًا ويجبره على التمدد لملء المساحة المتاحة في حاوية Flex (Row, Column, Flex). لا يمتلك Expanded تمثيلًا بصريًا خاصًا به — فهو يدير فقط القيود (constraints) المنقولة إلى العنصر الفرعي.
في جوهر Expanded تكمن آلية Flex التي يوفرها إطار Flutter. عندما يحسب Row أو Column أحجام أبنائهما، يخصصان أولاً مساحة للعناصر غير المرنة (العناصر العادية ذات الأحجام الثابتة)، ثم يوزعان المساحة المتبقية بين أبناء Expanded و Flexible بشكل متناسب مع معاملات flex الخاصة بهم.
يستخدم Expanded Flexible.fit = FlexFit.tight. هذا يعني أن ابن Expanded يجب أن يشغل كل المساحة المخصصة، حتى لو كان حجمه أصغر. على عكس Flexible مع Fit.loose، حيث يمكن أن يكون الابن أصغر من المساحة المخصصة، يقوم Expanded بتمديد المحتوى بشكل إجباري.
الخلاصة: Expanded هو الأداة الرئيسية لإنشاء تخطيطات متناسبة في Flutter. استخدمه عندما تحتاج إلى أن يملأ عنصر كل العرض أو الارتفاع المتاح بشكل مضمون.
Expanded و Flexible كلاهما يوزع المساحة في حاويات Flex، لكنهما يتصرفان بشكل مختلف جوهريًا. يكمن الاختلاف في خاصية fit، التي تحدد ما إذا كان الابن يمكن أن يكون أصغر من المساحة المتاحة.
لدى Expanded نموذج سلوك صارم: fit الخاص به يساوي FlexFit.tight. هذا يعني أن العنصر الفرعي يتلقى قيودًا مساوية للمساحة المتاحة — لا أكثر ولا أقل. إذا كان الابن أصغر، فإنه يتمدد. إذا كان أكبر، فإنه ينكمش. يستخدم Flexible FlexFit.loose، مما يسمح للعنصر الفرعي أن يكون بأي حجم ضمن المساحة المخصصة.
عمليًا: إذا كانت Row تحتوي على Expanded مع flex=1، فسيشغل كل منهما نصف العرض بالضبط. إذا استبدلتهما بـ Flexible مع fit.loose، فقد يكون كل ابن أصغر من النصف إذا كان حجمه أصغر — ستبقى المساحة المتبقية فارغة.
الخلاصة: استخدم Expanded للتخطيطات المتناسبة الصارمة، و Flexible عندما يمكن أن يكون الابن أصغر من المساحة المتاحة. إذا لم تكن متأكدًا — ابدأ بـ Expanded، فهو يعطي سلوكًا أكثر قابلية للتنبؤ.
معامل Flex (parameter flex) هو قيمة رقمية تحدد حصة المساحة المتاحة التي سيحصل عليها Expanded. افتراضيًا flex=1، مما يعني توزيعًا متساويًا بين جميع أبناء Expanded.
تعمل خوارزمية التوزيع على ثلاث خطوات. أولاً: يحسب Flutter الحجم الجوهري لجميع الأبناء غير المرنين. ثانيًا: تقسيم المساحة المتبقية على مجموع جميع معاملات flex. ثالثًا: يحصل كل Expanded على حصة تساوي معامل flex الخاص به مضروبًا في حجم وحدة flex واحدة.
على سبيل المثال، Row بعرض 300px تحتوي على Expanded: الأول بـ flex=2، والثاني بـ flex=1. المساحة الحرة (300px ناقص الأبناء غير المرنين) تُقسم إلى 3 أجزاء. الأول يحصل على 2/3، والثاني على 1/3. إذا لم يكن هناك أبناء غير مرنين، الأول يحصل على 200px، والثاني على 100px.
يمكن أن يكون معامل flex أي عدد صحيح موجب. القيمة 0 هي حالة خاصة: Expanded مع flex=0 يتصرف كعنصر غير مرن عادي، مشغلاً الحد الأدنى من المساحة حسب حجم الابن. هذا السلوك مكافئ لعدم وجود Expanded.
الخلاصة: معامل flex هو المفتاح لبناء تخطيطات مرنة. استخدم النسب 1:1 للأعمدة المتساوية، 2:1 للوحات مع منطقة رئيسية وجانبية، 3:1 للواجهات ذات التنقل الضيق.
مثال 1 يوضح الاستخدام الأساسي لـ Expanded في Row لإنشاء ثلاثة أعمدة متساوية.
Row(
children: [
Expanded(
child: Container(
color: Colors.red,
),
),
Expanded(
child: Container(
color: Colors.green,
),
),
Expanded(
child: Container(
color: Colors.blue,
),
),
],
)
في هذا المثال، ثلاث Expanded مع flex=1 (افتراضيًا) تقسم عرض Row بالتساوي. تمتد الحاويات إلى الارتفاع الكامل المحدد بواسطة Row وتشغل حصصًا متساوية. هذا النهج مناسب لإنشاء تخطيطات قائمة على الأعمدة بتوزيع نسبي.
مثال 2 يوضح استخدام معاملات flex مختلفة لإنشاء تخطيط مع شريط جانبي ومحتوى رئيسي.
Row(
children: [
Expanded(
flex: 1,
child: Container(
color: Colors.grey.200,
child: const Center(
child: Text('الشريط الجانبي'),
),
),
),
Expanded(
flex: 3,
child: Container(
color: Colors.white,
child: const Center(
child: Text('منطقة المحتوى'),
),
),
),
],
)
المثال الثاني ينشئ تخطيطًا نموذجيًا مع شريط جانبي (25%) ومنطقة محتوى رئيسي (75%). flex=1 و flex=3 يعطيان نسبة 1:3. عندما يتغير عرض الشاشة، تُحفظ النسب تلقائيًا — هذا هو أساس الواجهات المتجاوبة.
الخلاصة: Expanded مع معاملات flex مختلفة هو أداة قياسية لبناء تخطيطات متجاوبة. الجمع بين Expanded في Column يسمح بإنشاء ترتيبات نسبية أفقية وعمودية.
خطأ 1: استخدام Expanded خارج Row أو Column أو Flex. إذا وضعت Expanded مباشرة في Stack أو ListView أو أي حاوية أخرى غير Flex، يطلق Flutter LayoutException مع الرسالة "Expanded widgets must be placed inside Flex widgets". الحل: تحقق من العنصر الأب — فقط Row أو Column أو Flex.
خطأ 2: وضع Expanded داخل ListView دون تحديد shrinkWrap. ListView افتراضيًا له ارتفاع لا نهائي في اتجاه التمرير، ولا يستطيع Expanded حساب حصته. الحل: استخدم shrinkWrap: true أو لف ListView في SizedBox بارتفاع ثابت.
خطأ 3: Expanded متعددة مع flex إجمالي يتجاوز المساحة المتاحة. إذا كانت Row ذات عرض محدود تحتوي على Expanded بالإضافة إلى عناصر ذات حجم جوهري كبير، قد يحدث تجاوز (overflow). الحل: تحقق من الأحجام الدنيا للأبناء غير المرنين واستخدم FittedBox أو Flex fit إذا لزم الأمر.
خطأ 4: Expanded متداخلة في Column داخل Row. إذا كان Expanded داخل Column يحتوي على Expanded آخر داخل Row، قد ينشأ تضارب في القيود. الحل: حدد عمق التداخل أو استخدم ConstrainedBox لتحديد الأبعاد بشكل صريح في المستويات المتوسطة.
الخلاصة: Expanded يتطلب سياقًا أبويًا صحيحًا. تحقق دائمًا من أن Expanded موضوع مباشرة في Row أو Column أو Flex، وتجنب التداخل دون أبعاد صريحة.
الأسئلة الشائعة
SizedBox.expand يمد العنصر الفرعي قسرًا إلى الأبعاد المحددة بواسطة القيود الخارجية، لكنه لا يشارك في توزيع flex. يعمل Expanded فقط داخل حاويات Flex ويأخذ معامل flex في الاعتبار عند توزيع المساحة الحرة بين الأبناء.
لا. Stack ليس حاوية Flex، واستخدام Expanded داخله سيسبب LayoutException. لتمديد الأبناء في Stack، استخدم Positioned.fill أو BoxConstraints.expand.
افتراضيًا flex=1. جميع Expanded بدون flex صريح يحصلون على حصص متساوية من المساحة الحرة. إذا كانت Row تحتوي على ثلاث Expanded بدون flex، فسيشغل كل منها ثلث المساحة المتاحة بالضبط.
ضع Expanded في Row للتمديد الأفقي. للتمديد العمودي استخدم Expanded داخل Column. إذا كنت بحاجة إلى تحديد الأبعاد، لف Expanded أو ابنه في SizedBox.
Expanded يعمل مع Flex، بما في ذلك Row و Column كفئات فرعية. Wrap ليس حاوية Flex ولا يدعم Expanded. لتوزيع المساحة في Wrap استخدم طرقًا أخرى، مثل RunAlignment.
الخلاصة
سنقوم بتطوير تطبيق جوال جاهز
تقدم IT Sectr تطبيقات iOS وAndroid للشركات الناشئة والشركات منذ عام 2017. سوف نقدم لك النصح ونقترح أفضل حل.
اقرأ أيضًا