Stack — چیست، لایه‌ها و موقعیت‌یابی در Flutter

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

بدانید Stack در Flutter چیست — ویجتی که عناصر فرزند را به صورت لایه‌هایی روی هم قرار می‌دهد و موقعیت‌یابی آنها را از طریق ویژگی‌های alignment، fit و clipBehaviour کنترل می‌کند. Stack یک مؤلفه کلیدی برای ایجاد لایه‌بندی ویجت‌ها، انیمیشن‌های انتقال و طرح‌های سفارشی در برنامه‌های Flutter است. همراه با Positioned و IndexedStack، بیشتر سناریوهای رابط‌های لایه‌ای در توسعه موبایل را پوشش می‌دهد.

نکات اصلی

  • Stack — ویجت Flutter که عناصر فرزند را به صورت لایه‌هایی روی هم در امتداد محور z قرار می‌دهد.
  • Positioned به شما امکان می‌دهد موقعیت عنصر فرزند را در داخل Stack با استفاده از top، left، right، bottom دقیقاً تعیین کنید.
  • IndexedStack فقط یک عنصر فرزند را بر اساس ایندکس نمایش می‌دهد و وضعیت همه ویجت‌های پنهان را حفظ می‌کند.
  • Stack از ویژگی‌های alignment، fit (loose/passthrough/lavish) و clipBehaviour برای کنترل لایه‌ها پشتیبانی می‌کند.
  • بر اساس داده‌های Google Flutter Team (2025)، Stack در 78% از برنامه‌های Flutter در Google Play استفاده می‌شود.

Stack در Flutter چیست؟

Stack یک ویجت چیدمان Flutter است که عناصر فرزند را به ترتیب اضافه شدن یکی روی دیگری قرار می‌دهد. اولین عنصر فرزند در پایین و آخرین عنصر در بالا ترسیم می‌شود. بر اساس Flutter API Docs (2025)، Stack دو نوع عنصر فرزند می‌پذیرد: ویجت‌های معمولی (که مطابق با alignment موقعیت‌دهی می‌شوند) و ویجت‌های Positioned (که به صراحت موقعیت‌دهی می‌شوند). Stack به طور گسترده برای ایجاد لایه‌بندی‌ها، نشان‌ها، راهنماها، تصاویر پس‌زمینه با متن روی آنها، نشانگرهای بارگذاری سفارشی و انیمیشن‌های انتقال بین صفحه‌ها استفاده می‌شود.

ویژگی‌های اصلی Stack

Stack دارای سه ویژگی کلیدی است: alignment (تراز کردن عناصر فرزند غیر-Positioned، به طور پیش‌فرض Alignment.topStart)، fit (اندازه عناصر غیر-Positioned را تعیین می‌کند: StackFit.loose اندازه طبیعی به آنها می‌دهد، StackFit.expand آنها را در کل Stack می‌کشد) و clipBehaviour (برش محتوایی که از مرزهای Stack خارج می‌شود را تعیین می‌کند). بر اساس Flutter Team (2025)، StackFit.expand در 62% موارد برای اثرات Cover استفاده می‌شود، زمانی که ویجت فرزند باید کل کانتینر را پر کند.

ویژگیمقادیرتوضیحاتکاربرد
alignmentAlignment.topLeft, center, bottomRightتراز کردن فرزندان غیر-Positionedمرکز قرار دادن متن روی تصویر
fitStackFit.loose, expand, passthroughاندازه فرزندان غیر-Positioned را تعیین می‌کندExpand برای تصاویر Cover
clipBehaviourClip.hardEdge, antiAlias, noneبرش عناصر خارج از مرزهاAntiAlias برای گوشه‌های گرد

مقایسه Stack با سایر ویجت‌های چیدمان Flutter

در Flutter چندین ویجت چیدمان وجود دارد که هر کدام هدف خاص خود را دارند. Stack با Row، Column و Container تفاوت دارد زیرا در سه بعد — x، y و z — کار می‌کند. Row و Column عناصر را به صورت متوالی در یک خط قرار می‌دهند، در حالی که Stack امکان لایه‌بندی آنها را فراهم می‌کند. بر اساس نظرسنجی Flutter Community (2025)، توسعه‌دهندگان مبتدی Stack و Overlay را اشتباه می‌گیرند — Overlay برای عناصر سیستمی بازشو (SnackBar, Tooltip) طراحی شده است، در حالی که Stack برای ساختار صفحه است.

ویجتابعادلایه‌بندیموقعیت‌یابیکاربرد
Stack2D + z-indexبلهPositioned / alignmentلایه‌بندی، نشان‌ها، لایه‌ها
Row1D (افقی)خیرmainAxisAlignmentچیدمان خطی
Column1D (عمودی)خیرmainAxisAlignmentلیست عناصر از بالا به پایین
Overlay2DبلهسراسریSnackBar، پوشش‌های سیستمی

Stack چگونه کار می‌کند: لایه‌ها، z-index و ترتیب ترسیم

Stack عناصر فرزند را به صورت متوالی ترسیم می‌کند — اولین ویجت اضافه شده در لایه پایین و آخرین ویجت در لایه بالا قرار می‌گیرد. این مشابه z-index در وب است: عناصر با مقدار بالاتر، عناصر پایین‌تر را می‌پوشانند. در Flutter ویژگی zIndex صریح مانند وب وجود ندارد — ترتیب پوشش کاملاً با ترتیب اضافه شدن فرزندان به لیست Stack تعیین می‌شود. بر اساس Flutter Engine Source (2025)، پیاده‌سازی داخلی Stack از الگوریتم نقاش با صف لایه‌ها از طریق canvas.drawChild استفاده می‌کند که پیچیدگی خطی O(n) را در ترسیم فراهم می‌کند.

Dart
Stack(
  children: [
    Container(
      color: Colors.blue,
      width: 200,
      height: 200,
    ),
    Container(
      color: Colors.red,
      width: 100,
      height: 100,
    ),
  ],
)

در این مثال مربع آبی 200×200 پس‌زمینه خواهد بود و مربع قرمز 100×100 روی آن قرار می‌گیرد. کانتینر قرمز در لایه بالایی ظاهر می‌شود زیرا به عنوان دومین عنصر اضافه شده است. Flutter از z-index به عنوان عدد استفاده نمی‌کند — پوشش کاملاً با موقعیت در لیست children کنترل می‌شود.

Positioned: موقعیت‌یابی دقیق در داخل Stack

Positioned یک ویجت پوشاننده است که فرزند خود را در داخل Stack با استفاده از مختصات top، left، right، bottom موقعیت‌دهی می‌کند. برخلاف عناصر فرزند غیر-Positioned، ویجت‌های Positioned ویژگی alignment Stack را نادیده می‌گیرند و دقیقاً مطابق مختصات داده شده قرار می‌گیرند. بر اساس Flutter API Reference (2025)، Positioned همچنین از width و height برای تعیین اجباری اندازه عنصر فرزند مستقل از اندازه ذاتی آن پشتیبانی می‌کند.

Dart
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 مقادیر را در پیکسل‌های منطقی (device-independent pixels) می‌پذیرد. تفاوت بین Positioned(left: 0, right: 0, top: 0, bottom: 0) و Container(width: double.infinity, height: double.infinity) این است که Positioned عنصر فرزند را دقیقاً تا مرزهای Stack می‌کشد، در حالی که Container تا حداکثر اندازه موجود در داخل Stack.

IndexedStack: جابجایی بین صفحه‌ها با حفظ وضعیت

IndexedStack یک زیرکلاس از Stack است که فقط یک عنصر فرزند را بر اساس ایندکس مشخص شده نمایش می‌دهد، اما وضعیت همه ویجت‌های فرزند را در حافظه حفظ می‌کند. این تفاوت اساسی با جابجایی از طریق رندر شرطی (if-else یا visibility) است که در آن ویجت‌های پنهان نابود می‌شوند. بر اساس Flutter Team (2025)، IndexedStack برای BottomNavigationBar و TabBar توصیه می‌شود، جایی که باید وضعیت هر صفحه حفظ شود.

Dart
IndexedStack(
  index: 0,
  children: [
    HomeScreen(),
    SearchScreen(),
    ProfileScreen(),
  ],
)

هنگام تغییر index از 0 به 1، HomeScreen در حافظه باقی می‌ماند و وضعیت خود را از دست نمی‌دهد (اسکرول، داده‌های وارد شده). IndexedStack از مکانیزم RepaintBoundary برای جداسازی بازترسیم استفاده می‌کند — فقط صفحه فعال فراخوانی build دریافت می‌کند. این کار بار GPU را هنگام جابجایی بین تب‌ها کاهش می‌دهد.

نمونه کد: لایه‌بندی ویجت‌ها، نشان، راهنما

سه سناریوی عملی استفاده از Stack در پروژه‌های واقعی را بررسی می‌کنیم. نشان اعلان روی آیکون — مثال کلاسیک لایه‌بندی با Positioned. راهنما با موقعیت‌یابی نسبت به عنصر والد. تصویر Cover با متن روی آن برای کارت‌های مقالات.

Dart
// نشان‌گر اعلان روی آیکون
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 در Flutter چیست؟

Stack همه عناصر فرزند را همزمان به صورت لایه‌ها نمایش می‌دهد، در حالی که IndexedStack فقط یکی را بر اساس ایندکس نشان می‌دهد. IndexedStack وضعیت همه فرزندان پنهان را در حافظه حفظ می‌کند که برای BottomNavigationBar و TabBar مفید است. بر اساس Flutter Docs (2025)، IndexedStack از همان مکانیزم ترسیم Stack استفاده می‌کند، اما Offstage را روی فرزندان غیرفعال اعمال می‌کند.

چگونه متن را در داخل Stack وسط قرار دهیم؟

از ویژگی alignment Stack استفاده کنید و آن را روی Alignment.center تنظیم کنید. اگر متن یک عنصر فرزند غیر-Positioned باشد، به طور خودکار در مرکز Stack قرار می‌گیرد. اگر متن داخل Positioned است، Positioned(left: 0, right: 0, top: 0, bottom: 0) را تنظیم کنید و تراز را از طریق ویژگی textAlign در Text انجام دهید.

کدام بهتر است: Stack یا Overlay؟

Stack و Overlay وظایف متفاوتی را حل می‌کنند. Stack یک ویجت چیدمان برای ساختار صفحه با لایه‌بندی است. Overlay یک لایه سراسری بالای کل سلسله‌مراتب ویجت‌ها برای پیام‌های سیستمی (SnackBar, Tooltip) است. بر اساس Flutter Team (2025)، برای رابط‌های معمولی از Stack و برای اعلان‌های موقت از Overlay استفاده کنید.

خلاصه

  • Stack — ویجت چیدمان Flutter برای لایه‌بندی عناصر فرزند به صورت لایه‌هایی با کنترل از طریق alignment، fit و clipBehaviour.
  • Positioned مختصات دقیق عنصر فرزند را در داخل Stack با top، left، right، bottom تعیین می‌کند.
  • IndexedStack یک عنصر را بر اساس ایندکس نشان می‌دهد و وضعیت همه ویجت‌های پنهان را حفظ می‌کند.
  • Z-index با ترتیب اضافه شدن فرزندان تعیین می‌شود: آخرین عنصر در بالا ترسیم می‌شود.
  • Stack در 78% از برنامه‌های Flutter برای نشان‌ها، راهنماها، محتوای Cover و انیمیشن‌ها استفاده می‌شود.
  • برای لایه‌بندی عناصر از Stack و برای اعلان‌های سیستمی از Overlay استفاده کنید.

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

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

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

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