Expanded: چیست و اصل کار در Flutter

نویسنده: IT Sectr منتشر شده: 2026-07-03 زمان مطالعه: 6 دقیقه

Expanded ویجت Flutter است که باعث می‌شود عنصر فرزند تمام فضای موجود را در کانتینر Flex پر کند. وقتی Row یا Column فضا را بین فرزندان توزیع می‌کنند، Expanded فضای خالی را پس از در نظر گرفتن عناصر غیرانعطاف‌پذیر برمی‌دارد. طبق مستندات رسمی Flutter (2026)، Expanded یکی از پراستفاده‌ترین ویجت‌های layout است: در درصد‌بندی رابط‌ها، ساخت کارت‌ها، لیست‌ها و پنل‌ها به کار می‌رود. مزیت اصلی آن محاسبه خودکار عرض یا ارتفاع بر اساس ضریب flex بدون مشخص کردن صریح اندازه‌ها است.

نکات کلیدی

  • Expanded — ویجت layout که فرزند را به تمام فضای خالی در Row، Column یا Flex می‌کشد
  • ضریب Flex مشخص می‌کند هر Expanded چه سهمی از فضای خالی دریافت کند
  • Expanded با Flexible تفاوت دارد زیرا تمام فضای موجود را اجباری پر می‌کند
  • Stack از Expanded پشتیبانی نمی‌کند، فقط Row، Column و Flex
  • خطا استفاده از Expanded خارج از کانتینر Flex باعث LayoutException می‌شود

Expanded چیست

Expanded یک ویجت wrapper است که child می‌گیرد و آن را مجبور می‌کند برای پر کردن فضای موجود در کانتینر 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 vs Flexible: تفاوت‌های کلیدی

Expanded و Flexible — هر دو فضا را در کانتینرهای Flex توزیع می‌کنند، اما رفتار اساساً متفاوتی دارند. تفاوت در ویژگی fit است که تعیین می‌کند آیا فرزند می‌تواند از فضای موجود کوچک‌تر باشد.

Expanded مدل رفتاری سختی دارد: fit آن برابر FlexFit.tight است. یعنی ویجت فرزند constraints برابر با فضای موجود دریافت می‌کند — نه بیشتر، نه کمتر. اگر فرزند کوچک‌تر باشد، کشیده می‌شود. اگر بزرگ‌تر باشد، فشرده می‌شود. Flexible از FlexFit.loose استفاده می‌کند و به عنصر فرزند اجازه می‌دهد هر اندازه‌ای در محدوده فضای اختصاص یافته داشته باشد.

در عمل: اگر درون Row دو Expanded با flex=1 وجود داشته باشد، هر کدام دقیقاً نیمی از عرض را می‌گیرند. اگر آنها را با Flexible با fit.loose جایگزین کنید، هر فرزند می‌تواند اگر اندازه خودش کوچک‌تر باشد، کمتر از نصف باشد — فضای باقی‌مانده خالی می‌ماند.

نتیجه: برای طرح‌های تناسبی سخت از Expanded استفاده کنید، Flexible — زمانی که فرزند می‌تواند از فضای موجود کوچک‌تر باشد. اگر مطمئن نیستید — از Expanded شروع کنید، رفتار قابل‌پیش‌بینی‌تری دارد.

ضریب Flex: چگونه فضا توزیع می‌شود

ضریب Flex (پارامتر flex) — مقدار عددی که سهم فضای موجود را که Expanded دریافت می‌کند تعیین می‌کند. به طور پیش‌فرض flex=1، یعنی توزیع برابر بین تمام فرزندان Expanded.

الگوریتم توزیع در سه مرحله کار می‌کند. مرحله اول: Flutter intrinsic size تمام فرزندان غیرانعطاف‌پذیر را محاسبه می‌کند. مرحله دوم: فضای باقی‌مانده بر مجموع تمام ضریب‌های 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 برای رابط‌های با ناوبری باریک استفاده کنید.

نمونه کد با Expanded

مثال 1 استفاده پایه از Expanded در Row برای ایجاد سه ستون مساوی را نشان می‌دهد.

dart
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 برای ایجاد طرح با پنل کناری و محتوای اصلی را نشان می‌دهد.

dart
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('ناحیه محتوا'),
        ),
      ),
    ),
  ],
)

مثال دوم یک layout معمولی با پنل کناری (25%) و ناحیه اصلی (75%) ایجاد می‌کند. flex=1 و flex=3 نسبت 1:3 را می‌دهند. با تغییر عرض صفحه، نسبت‌ها به طور خودکار حفظ می‌شوند — این اساس رابط‌های تطبیقی است.

نتیجه: Expanded با ضریب‌های مختلف flex ابزار استاندارد برای ساخت طرح‌های تطبیقی است. ترکیب Expanded در Column امکان ایجاد چیدمان‌های تناسبی افقی و عمودی را فراهم می‌کند.

خطاهای رایج در استفاده از Expanded

خطای 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 و همچنین ویجت‌هایی با intrinsic size بزرگ وجود داشته باشد، ممکن است overflow رخ دهد. راه‌حل: اندازه‌های حداقل فرزندان غیرانعطاف‌پذیر را بررسی کنید و در صورت لزوم از FittedBox یا Flex fit استفاده کنید.

خطای 4: Expanded تودرتو در Column داخل Row. اگر Expanded درون Column حاوی Expanded دیگری درون Row باشد، ممکن است تضاد constraints رخ دهد. راه‌حل: عمق تودرتو را محدود کنید یا از ConstrainedBox برای تعیین صریح اندازه‌ها در سطوح میانی استفاده کنید.

نتیجه: Expanded به زمینه والد صحیح نیاز دارد. همیشه بررسی کنید که Expanded مستقیماً در Row، Column یا Flex قرار دارد و از تودرتو بدون اندازه‌های صریح خودداری کنید.

سوالات متداول

Expanded چه تفاوتی با SizedBox.expand دارد؟

SizedBox.expand فرزند را به اندازه‌های تعیین شده توسط constraints خارجی اجباری می‌کشد، اما در توزیع flex شرکت نمی‌کند. Expanded فقط درون کانتینرهای Flex کار می‌کند و ضریب flex را در توزیع فضای خالی بین فرزندان در نظر می‌گیرد.

آیا می‌توان از Expanded درون Stack استفاده کرد؟

خیر. Stack یک کانتینر Flex نیست و استفاده از Expanded درون آن باعث LayoutException می‌شود. برای کشیدن فرزندان در Stack از Positioned.fill یا BoxConstraints.expand استفاده کنید.

اگر ضریب flex مشخص نشود چه اتفاقی می‌افتد؟

به طور پیش‌فرض flex=1. تمام Expanded بدون flex صریح سهم‌های مساوی از فضای خالی دریافت می‌کنند. اگر در Row سه Expanded بدون flex باشد، هر کدام دقیقاً یک سوم فضای موجود را اشغال می‌کنند.

چگونه Expanded را فقط برای عرض انجام دهیم نه ارتفاع؟

Expanded را در Row قرار دهید برای کشش افقی. برای کشش عمودی از Expanded درون Column استفاده کنید. اگر نیاز به محدود کردن اندازه‌ها دارید، Expanded یا فرزند آن را در SizedBox بپیچید.

آیا Expanded با Wrap یا ویجت‌های Flex کار می‌کند؟

Expanded با Flex کار می‌کند، شامل Row و Column به عنوان زیرکلاس‌های آن. Wrap یک کانتینر Flex نیست و از Expanded پشتیبانی نمی‌کند. برای توزیع فضا در Wrap از روش‌های دیگری مانند RunAlignment استفاده کنید.

خلاصه

  • Expanded — ویجت برای کشش اجباری فرزند به تمام فضای موجود در کانتینر Flex
  • ضریب Flex نسبت توزیع فضای خالی بین چندین Expanded را تعیین می‌کند
  • تفاوت با Flexible: Expanded از tight fit (پر کردن اجباری) استفاده می‌کند، Flexible — loose fit (اختیاری)
  • خطا قرار دادن Expanded خارج از Row، Column یا Flex باعث LayoutException می‌شود
  • تطبیق‌پذیری: تناسب طرح با تغییر اندازه صفحه به طور خودکار حفظ می‌شود
  • توصیه: از Expanded به عنوان ابزار اصلی برای طرح‌های ستونی و پنلی در Flutter استفاده کنید

ما یک اپلیکیشن موبایل به صورت کلید در دست توسعه خواهیم داد

IT Sectr از سال 2017 برنامه‌های iOS و Android را برای استارتاپ‌ها و کسب‌وکارها ایجاد می‌کند. ما به شما مشاوره می‌دهیم و بهترین راه‌حل را پیشنهاد خواهیم کرد.

بحث درباره پروژه

همچنین بخوانید