Flexible: ما هو، مبدأ العمل والإعداد في تطوير التطبيقات المحمولة

المؤلف: IT Sectr نُشر: 2026-07-03 وقت القراءة: 6 دق

Flexible هو عنصر واجهة Flutter يتحكم في كيفية احتلال العنصر الفرعي للمساحة المتاحة في حاوية Flex. على عكس Expanded، لا يجبر Flexible العنصر الفرعي على ملء المنطقة المخصصة بالكامل — يمكن أن يكون العنصر الفرعي أصغر، وتبقى المساحة المتبقية فارغة. وفقًا للوثائق الرسمية لـ Flutter (2026)، فإن Flexible ضروري في السيناريوهات التي تتطلب توزيعًا مرنًا للمساحة دون تمديد إجباري: أزرار بعرض أدنى، كتل نصية بحجم طبيعي وعناصر ذات intrinsic constraints.

النقاط الرئيسية

  • Flexible هو عنصر واجهة تخطيط للتوزيع المرن للمساحة في Row أو Column أو Flex
  • FlexFit.loose يسمح للعنصر الفرعي بأن يكون أصغر من المساحة المخصصة، FlexFit.tight يجبر على الملء
  • Flexible مع loose مناسب للعناصر التي يجب أن يحدد محتواها حجمها
  • الفرق عن Expanded: Expanded ليس لديه معامل fit ويعمل دائمًا كـ tight
  • عامل flex يعمل بنفس الطريقة لكل من Flexible و Expanded — حصة المساحة الحرة

ما هو Flexible

Flexible هو عنصر واجهة غلاف يوفر مساحة مرنة لعنصر فرعي في حاوية Flex. Flexible، مثل Expanded، يشارك في توزيع المساحة الحرة، ولكن مع فرق رئيسي: يمكن لعنصر Flexible الفرعي أن يشغل مساحة أقل من المخصصة إذا كان حجمه أصغر من المساحة المتاحة.

يستخدم Flexible خوارزمية Flex الخاصة بـ Flutter لحساب المساحة المتاحة. أولاً، يستعلم الإطار جميع العناصر الفرعية غير المرنة (العناصر بدون Flexible/Expanded) ويحسب حجمها الذاتي. يتم تقسيم المساحة المتبقية بين العناصر الفرعية المرنة بشكل متناسب مع عوامل flex الخاصة بها. بعد تخصيص المساحة، يتحقق Flexible من fit — إذا كان loose، يتلقى العنصر الفرعي قيدًا بـ «لا أكبر من المخصص»، مما يسمح له بالبقاء صغيرًا.

ميزة Flexible: إذا كان للعنصر الفرعي أحجامه الدنيا الخاصة (على سبيل المثال، Text مع سلسلة طويلة)، يخصص Flexible المساحة المطلوبة دون تمديد إجباري. هذا يجعل Flexible لا غنى عنه للعناصر التي يجب أن يحدد محتواها حجمها بدلاً من الحاوية.

الخلاصة: استخدم Flexible عندما تحتاج إلى حجز مساحة لعنصر ولكن دون إجباره على التمدد. هذا يحافظ على الأحجام الطبيعية للمحتوى مع الحفاظ على توزيع مرن للتخطيط.

FlexFit.tight مقابل FlexFit.loose

FlexFit هو تعداد من قيمتين: tight و loose. يحدد اختيار fit ما إذا كان سيتم تمديد العنصر الفرعي قسريًا إلى حجم المساحة المخصصة.

FlexFit.tight: يتلقى العنصر الفرعي tight constraints — الأحجام الدنيا والقصوى تساوي المساحة المخصصة. يجب أن يشغل العنصر الفرعي بالضبط المساحة التي خصصتها خوارزمية Flex. إذا كان العنصر الفرعي أصغر — يتم تمديده. إذا كان أكبر — يتم تصغيره. السلوك مطابق لـ Expanded.

FlexFit.loose: يتلقى العنصر الفرعي loose constraints — الحجم الأدنى هو 0، والأقصى يساوي المساحة المخصصة. يمكن أن يكون العنصر الفرعي بأي حجم من 0 إلى الحد الأقصى. إذا كان العنصر الفرعي صغيرًا (على سبيل المثال، Text بسلسلة قصيرة)، فإنه يشغل عرضه الطبيعي، وتبقى المساحة المتبقية فارغة.

الخلاصة: FlexFit.loose هو الخيار لكتل النص والعناصر ذات الحجم الطبيعي. FlexFit.tight هو للتخطيطات العمودية الصارمة حيث يجب أن تكون جميع العناصر بنفس العرض أو الارتفاع.

متى تستخدم Flexible بدلاً من Expanded

Flexible و Expanded يبدوان متشابهين لكنهما يحلان مهامًا مختلفة. Expanded دائمًا يمدد العنصر الفرعي لملء كل المساحة المتاحة. يمكن لـ Flexible ترك مساحة فارغة حول العنصر الفرعي إذا كان حجم المحتوى أصغر من الحصة المخصصة.

سيناريو لـ Flexible: داخل Row هناك زران. الأول — «شراء» (نص قصير)، الثاني — «أضف إلى السلة» (نص طويل). مع Expanded، يتمدد كلا الزراين بنفس العرض، وسيكون للنص القصير هوامش ضخمة. مع Flexible، يأخذ كل زر عرض نصه، وتبقى المساحة الحرة بينهما أو عند الحواف.

سيناريو لـ Expanded: داخل Column هناك ثلاث بطاقات يجب أن تشغل ارتفاعًا متساويًا بغض النظر عن المحتوى. يقسم Expanded الارتفاع المتاح بالتساوي، وتمتد كل بطاقة إلى نفس الحجم. Flexible مع loose لن يعمل هنا — ستبقى البطاقة الصغيرة صغيرة، مما يكسر التصميم الموحد.

الخلاصة: اختر Flexible عندما يحدد المحتوى حجم العنصر وتكون المساحة الفارغة حوله مقبولة. اختر Expanded عندما يجب أن تكون جميع العناصر بنفس الحجم بغض النظر عن المحتوى.

أمثلة كود مع Flexible

مثال 1 يوضح الاستخدام الأساسي لـ Flexible مع FlexFit.loose في Row.

dart
Row(
  children: [
    Flexible(
      fit: FlexFit.loose,
      child: Container(
        color: Colors.amber,
        child: const Text('قصير'),
      ),
    ),
    Flexible(
      fit: FlexFit.loose,
      child: Container(
        color: Colors.cyan,
        child: const Text('نص طويل للعرض'),
      ),
    ),
  ],
)

في المثال، كلا Flexible يستخدمان loose fit. الحاوية الأولى بنص قصير تشغل عرضها الطبيعي. الثانية بنص طويل — عرضها الخاص. تخصص Row لكل منهما نصف العرض المتاح، لكن loose fit يسمح للحاويات بأن تكون أصغر، وتبقى المساحة الحرة فارغة بينهما.

مثال 2 — مقارنة Flexible مع Tight و Loose fit في Column.

dart
Column(
  children: [
    Flexible(
      fit: FlexFit.tight,
      child: const Card(
        child: ListTile(
          title: Text('Tight — الارتفاع الكامل الممدود'),
        ),
      ),
    ),
    const SizedBox(
      height: 8,
    ),
    Flexible(
      fit: FlexFit.loose,
      child: const Card(
        child: ListTile(
          title: Text('Loose — الارتفاع الطبيعي'),
        ),
      ),
    ),
  ],
)

في Column، أول Flexible (tight) يمدد البطاقة إلى نصف الارتفاع المتاح. ثاني Flexible (loose) — البطاقة تشغل الارتفاع وفقًا لمحتواها، وتبقى المساحة المتبقية فارغة. بصريًا، يمكن رؤية كيف يملأ tight المساحة قسريًا، بينما يحافظ loose على حجم مضغوط.

الخلاصة: في كود الإنتاج، يُستخدم Flexible مع loose لحقول النماذج والأزرار وكتل النص. Flexible مع tight مكافئ لـ Expanded ويُستخدم للتوزيع المتساوي.

الأخطاء الشائعة عند استخدام Flexible

الخطأ 1: استخدام Flexible خارج حاوية Flex. مثل Expanded، يرمي Flexible LayoutException إذا لم يكن داخل Row أو Column أو Flex. الحل: تحقق دائمًا من سلسلة العناصر الأصلية.

الخطأ 2: الخلط بين Flexible و Expanded. غالبًا ما يستخدم المطورون Expanded عندما يحتاجون إلى Flexible مع loose fit، والعكس صحيح. النتيجة: Expanded يمدد عنصرًا بنص قصير، مما يخلق هوامش فارغة كبيرة. الحل: إذا كان حجم العنصر يمكن أن يكون أصغر من المخصص — استخدم Flexible(fit: FlexFit.loose).

الخطأ 3: عامل flex صفري. يتصرف Flexible مع flex=0 كعنصر غير مرن، مما قد يكون غير بديهي. يتوقع المطور سلوكًا مرنًا، لكن العنصر يشغل الحجم الأدنى. الحل: يجب أن يكون flex ≥1 للتوزيع النشط للمساحة.

الخطأ 4: Flexible داخل ScrollView بدون قيود على الحجم. إذا كان Flexible داخل Column داخل SingleChildScrollView، توفر حاوية التمرير مساحة لا نهائية، ولا يعمل توزيع flex. الحل: قيّد حجم حاوية التمرير باستخدام SizedBox أو ConstrainedBox.

الخلاصة: يتطلب Flexible نفس الاهتمام بسياق العنصر الأصل مثل Expanded. الاختلاف الوحيد هو fit — اختره عن قصد حسب المهمة.

الأسئلة الشائعة

ما الفرق بين Flexible و Expanded؟

Expanded هو Flexible مع fit=tight ثابت. الفرق هو أن Expanded لديه ارتباط صارم بملء كل المساحة المتاحة، بينما يمكن لـ Flexible استخدام loose fit للحفاظ على الحجم الطبيعي للعنصر الفرعي.

أي fit يجب أن أختار للأزرار في Row؟

للأزرار بأطوال نصية مختلفة، استخدم Flexible(fit: FlexFit.loose). سيأخذ كل زر عرض محتواه، ولن يكون هناك عدم تناسب بينها. Expanded سيجعل جميع الأزرار بنفس العرض.

كيف أجعل Flexible يتصرف مثل Expanded؟

اضبط fit: FlexFit.tight — سيجبر Flexible العنصر الفرعي على ملء كل المساحة المخصصة. في هذا الوضع، يكون Flexible مطابقًا تمامًا لـ Expanded في السلوك.

هل يمكن لـ Flexible تقليل حجم العنصر الفرعي؟

نعم، إذا كان العنصر الفرعي أكبر من المساحة المخصصة. يمرر Flexible قيودًا بحجم أقصى يساوي حصة حاوية Flex. إذا تجاوز العنصر الفرعي هذا الحجم، فإنه يتقلص ضمن القيود.

هل يعمل Flexible مباشرة مع حاوية Flex؟

نعم، يعمل Flexible مع أي حاوية Flex، بما في ذلك Row و Column وعنصر الواجهة الأساسي Flex باتجاه عشوائي. يسمح Flex بتعيين اتجاهات غير قياسية عبر mainAxisAlignment و crossAxisAlignment.

الملخص

  • Flexible هو عنصر واجهة للتوزيع المرن للمساحة دون تمديد إجباري للعنصر الفرعي
  • FlexFit.loose يحافظ على الحجم الطبيعي للمحتوى، FlexFit.tight يملأ المساحة قسريًا
  • Expanded هو حالة خاصة من Flexible مع fit=tight، استخدم Flexible عندما تحتاج إلى اختيار fit
  • عامل flex يعمل بنفس الطريقة لكل من Flexible و Expanded — حصة المساحة الحرة
  • Loose fit مثالي للأزرار وكتل النص والعناصر ذات المحتوى الديناميكي
  • توصية: استخدم Flexible مع loose للمكونات التي يحدد محتواها حجمها

سنقوم بتطوير تطبيق جوال جاهز

تقدم IT Sectr تطبيقات iOS وAndroid للشركات الناشئة والشركات منذ عام 2017. سوف نقدم لك النصح ونقترح أفضل حل.

مناقشة المشروع

اقرأ أيضًا