Column: چیدمان عمودی و پیکربندی کانتینر در Compose

نویسنده: IT Sectr منتشر شده: 2026-06-28 زمان مطالعه: 8 دقیقه

Column — یک کامپوننت Composable داخلی Jetpack Compose از بسته compose.foundation.layout است که عناصر فرزند را به صورت عمودی و یکی پس از دیگری قرار می‌دهد. Column معادل LinearLayout با جهت عمودی از سیستم View قدیمی است، اما برخلاف آن از توصیف اعلانی استفاده می‌کند و به طور خودکار به تغییرات وضعیت واکنش نشان می‌دهد. به گفته Google Android Developers, 2026، Column یکی از سه کانتینر پایه همراه با Row و Box است.

نکات اصلی

  • Column عناصر را با تنظیم Arrangement و Alignment به صورت عمودی قرار می‌دهد
  • Arrangement توزیع فضای بین عناصر را در جهت عمودی تعیین می‌کند
  • Alignment تراز افقی هر عنصر را در داخل Column مشخص می‌کند
  • وزن (weight) فضای آزاد را به نسبت بین عناصر توزیع می‌کند
  • IntrinsicSize به Column امکان می‌دهد اندازه خود را با حداقل/حداکثر عرض فرزندان تنظیم کند

Column در Jetpack Compose چیست

Column — یک تابع Composable است که پارامترهای اختیاری modifier، verticalArrangement، horizontalAlignment و content — لامبدا با ColumnScope را می‌پذیرد. در داخل Column، توابع Composable فرزند به ترتیب اعلان از بالا به پایین قرار می‌گیرند. ارتفاع Column برابر است با مجموع ارتفاع عناصر فرزند به اضافه فضای تعیین شده توسط Arrangement. عرض — بر اساس حداکثر عرض عنصر فرزند با در نظر گرفتن Alignment.

Column یک کانتینر نامرئی است: به طور پیش‌فرض پس‌زمینه یا حاشیه خاص خود را ندارد. اگر پس‌زمینه نیاز است — Modifier.background() را به خود Column اضافه کنید. برخلاف LazyColumn، Column همه عناصر فرزند را همزمان نمایش می‌دهد و از مجازی‌سازی پشتیبانی نمی‌کند. این بدان معناست که Column فقط برای مجموعه‌های داده کوچک — تا 10-15 عنصر — مناسب است. برای لیست‌های طولانی از LazyColumn استفاده کنید.

ColumnScope — یک receiver برای لامبدای content در Column است. این متد اصلاح‌کننده‌های اضافی را فراهم می‌کند که فقط در داخل Column کار می‌کنند: weight()، align()، alignByBaseline(). این اصلاح‌کننده‌ها در خارج از Column معنی ندارند زیرا به ویژگی چیدمان عمودی متکی هستند. به عنوان مثال، Modifier.align(Alignment.CenterHorizontally) عنصر فرزند را به صورت افقی در مرکز Column قرار می‌دهد.

پارامترهای Column: Arrangement, Alignment, Modifier

VerticalArrangement نحوه توزیع فضای عمودی بین عناصر را تعیین می‌کند. مقادیر موجود: Arrangement.Top (پیش‌فرض)، Bottom، Center، SpaceBetween، SpaceEvenly، SpaceAround. اگر ارتفاع Column از مجموع ارتفاع عناصر بیشتر باشد، Arrangement فضای آزاد را توزیع می‌کند. اگر عناصر تمام ارتفاع را اشغال کنند — Arrangement تأثیری ندارد.

HorizontalAlignment تراز افقی هر عنصر فرزند را تنظیم می‌کند. Alignment.Start (پیش‌فرض، LTR)، CenterHorizontally، End. Alignment روی هر عنصر به طور مستقل عمل می‌کند: اگر یک عنصر باریک و دیگری عریض باشد — اولی تراز می‌شود، دومی ممکن است از مرزهای Column خارج شود. Alignment فقط زمانی کار می‌کند که Column دارای عرض ثابت یا fillMaxWidth باشد.

Modifier برای Column: Column یک Modifier می‌پذیرد که به خود کانتینر اعمال می‌شود. Modifier.fillMaxWidth()، fillMaxHeight()، size()، padding() — همه اصلاح‌کننده‌های استاندارد کار می‌کنند. ویژگی: Modifier.height(IntrinsicSize.Min) Column را مجبور می‌کند حداقل ارتفاع را بر اساس عناصر فرزند با در نظر گرفتن Intrinsic measurement محاسبه کند.

kotlin
@Composable
fun ColumnArrangementDemo() {
    Column(
        modifier = Modifier.fillMaxSize().background(Color(0xFFF5F5F5)),
        verticalArrangement = Arrangement.SpaceEvenly,
        horizontalAlignment = Alignment.CenterHorizontally
    ) {
        Text("بالا", modifier = Modifier.background(Color.Cyan))
        Text("وسط", modifier = Modifier.background(Color.Magenta))
        Text("پایین", modifier = Modifier.background(Color.Yellow))
    }
}

    // IntrinsicSize: Column ارتفاع را با محتوا تنظیم می‌کند
@Composable
fun IntrinsicColumn() {
    Column(
        modifier = Modifier
            .height(IntrinsicSize.Min)
            .width(200.dp)
    ) {
        Text("متن کوتاه")
        Text("متن بسیار طولانی که در ستون پیچیده می‌شود")
    }
}
Arrangementرفتار
Arrangement.Topعناصر به بالا چسبیده، فضای آزاد در پایین
Arrangement.Centerعناصر در مرکز، فضا به طور مساوی در بالا و پایین تقسیم می‌شود
Arrangement.SpaceBetweenاولین عنصر در بالا، آخرین در پایین، بقیه به طور یکنواخت
Arrangement.SpaceEvenlyفاصله‌های مساوی بین همه عناصر و لبه‌ها
Arrangement.SpaceAroundفاصله‌های مساوی بین عناصر، نصف در لبه‌ها

وزن Column: توزیع فضا بین عناصر

Modifier.weight() — یک اصلاح‌کننده ColumnScope است که فضای خالی عمودی را بین عناصر Column به نسبت وزن‌های مشخص شده توزیع می‌کند. اگر Column 400dp ارتفاع را اشغال کند و عناصر فرزند در مجموع 100dp باشند، 300dp باقی‌مانده بین عناصر weight تقسیم می‌شود. عنصر با weight(2f) دو برابر بیشتر از عنصر با weight(1f) فضا دریافت می‌کند.

fill — دومین پارامتر weight: weight(weight: Float, fill: Boolean = true). اگر fill = true (پیش‌فرض)، عنصر تا تمام ارتفاع موجود کشیده می‌شود. اگر fill = false — عنصر فقط ارتفاع ذاتی خود را اشغال می‌کند و فضای باقی‌مانده خالی می‌ماند. این زمانی مفید است که عنصر باید به یک طرف چسبیده باشد، اما weight فقط نسبت توزیع فضای خالی را تعیین می‌کند.

محدودیت‌های weight: weight فقط در Column با ارتفاع ثابت یا fillMaxHeight() کار می‌کند. اگر ارتفاع Column توسط عناصر فرزند تعیین شود (wrap content)، وزن‌ها معنی ندارند — فضای خالی برای توزیع وجود ندارد. همچنین weight را نمی‌توان با Modifier.height() روی همان عنصر ترکیب کرد — آنها با هم تضاد دارند و weight نادیده گرفته می‌شود.

kotlin
@Composable
fun WeightedColumn() {
    Column(
        modifier = Modifier.fillMaxHeight().width(300.dp)
    ) {
        // 1/6 ارتفاع را می‌گیرد (وزن 1 از مجموع 1+2+3=6)
        Box(
            modifier = Modifier
                .weight(1f)
                .fillMaxWidth()
                .background(Color.Red)
        )
        // 2/6 ارتفاع را می‌گیرد
        Box(
            modifier = Modifier
                .weight(2f)
                .fillMaxWidth()
                .background(Color.Green)
        )
        // 3/6 ارتفاع را می‌گیرد
        Box(
            modifier = Modifier
                .weight(3f)
                .fillMaxWidth()
                .background(Color.Blue)
        )
    }
}

Column در مقابل LazyColumn: چه زمانی از کدام استفاده کنیم

Column همه عناصر فرزند را بلافاصله نمایش می‌دهد. اگر عناصر بیشتر از 10-15 باشند، Column بار قابل توجهی بر ترکیب‌بندی و اندازه‌گیری ایجاد می‌کند. LazyColumn، برعکس، فقط عناصر قابل مشاهده را رندر می‌کند و عناصر نامرئی را مجدداً استفاده می‌کند. برای لیست‌های طولانی، لیست‌های با هزاران عنصر، لیست‌های بی‌نهایت یا چت‌ها — LazyColumn اجباری است.

چه زمانی Column بهتر است: صفحه‌های با فرم‌ها (3-10 فیلد)، کارت‌های پروفایل، ستون‌های عمودی با آیکون‌ها، منو. Column همچنین از IntrinsicSize پشتیبانی می‌کند که برای ارتفاع تطبیقی مفید است. علاوه بر این، Column در اشکال‌زدایی ساده‌تر است — مجازی‌سازی وجود ندارد، همه عناصر در Layout Inspector قابل مشاهده هستند. برای UI ایستا، Column انتخاب درستی است.

LazyColumn ارائه می‌دهد: ذخیره‌سازی آیتم، هویت مبتنی بر کلید، انیمیشن افزودن/حذف (animateItemPlacement)، هدرهای چسبنده. اگر لیست شامل عناصر انواع مختلف باشد (viewType متفاوت) — از LazyColumn با sealed class در items استفاده کنید. Column از هدرهای چسبنده پشتیبانی نمی‌کند (باید از طریق scrollable Column شبیه‌سازی شوند). همچنین LazyColumn هنگام استفاده از GridCells از LazyVerticalGrid پشتیبانی می‌کند.

معیارColumnLazyColumn
تعداد عناصرتا 10-15هر تعداد
عملکردهمیشه همه را رندر می‌کندفقط قابل مشاهده + buffer
Scrollingاز طریق Modifier.verticalScrollداخلی
IntrinsicSizeپشتیبانی می‌کندپشتیبانی نمی‌کند
هدرهای چسبندهخیر (شبیه‌سازی)بله (stickyHeader)
انیمیشن عناصربدون انیمیشن داخلیanimateItemPlacement

نمونه‌های عملی استفاده از Column

صفحه پروفایل کاربر را در نظر بگیرید، جایی که Column به عنوان کانتینر اصلی برای آواتار، نام، بیو و دکمه‌های عملیات استفاده می‌شود. در اینجا Column با IntrinsicSize.Min خود را با محتوا تنظیم می‌کند و weight برای توزیع فضا بین بخش‌ها استفاده می‌شود.

kotlin
@Composable
fun UserProfileCard(name: String, bio: String) {
    Card(
        modifier = Modifier.fillMaxWidth().padding(16.dp),
        elevation = CardDefaults.cardElevation(defaultElevation = 4.dp)
    ) {
        Column(
            modifier = Modifier.fillMaxWidth().padding(16.dp),
            horizontalAlignment = Alignment.CenterHorizontally,
            verticalArrangement = Arrangement.spacedBy(8.dp)
        ) {
            // آواتار
            Icon(
                imageVector = Icons.Default.AccountCircle,
                contentDescription = "Avatar",
                modifier = Modifier.size(64.dp)
            )
            // نام
            Text(name, style = MaterialTheme.typography.headlineSmall)
            // بیو
            Text(bio, style = MaterialTheme.typography.bodyMedium,
                modifier = Modifier.padding(top = 4.dp))
            // دکمه‌های عملیات
            Row(
                horizontalArrangement = Arrangement.spacedBy(12.dp),
                modifier = Modifier.padding(top = 12.dp)
            ) {
                Button(onClick = { }) { Text("پیام") }
                OutlinedButton(onClick = { }) { Text("دنبال کردن") }
            }
        }
    }
}

در مثال، Column از Arrangement.spacedBy(8.dp) برای فاصله‌های یکنواخت بین عناصر استفاده می‌کند. horizontalAlignment = CenterHorizontally آواتار، نام و بیو را در مرکز قرار می‌دهد. Row در داخل Column — یک کانتینر تودرتو برای دکمه‌ها در یک ردیف. چنین ترکیبی از Column (چیدمان عمودی) و Row (چیدمان افقی) یک الگوی معمولی برای ساخت UI در Compose است.

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

تفاوت Column با LazyColumn از نظر عملکرد چیست؟

Column همه عناصر فرزند را بلافاصله رندر می‌کند که با 100+ عنصر باعث کاهش FPS می‌شود. LazyColumn فقط عناصر قابل مشاهده + بافر (معمولاً 3-5 صفحه) را رندر می‌کند. برای صفحه‌های ایستا با 3-10 عنصر، Column سریع‌تر است زیرا سربار مجازی‌سازی ندارد.

چگونه Column را قابل پیمایش کنیم؟

Modifier.verticalScroll(rememberScrollState()) را به Column اضافه کنید. این کار Column را قابل پیمایش می‌کند، اما مجازی‌سازی ارائه نمی‌دهد — همه عناصر همچنان بلافاصله رندر می‌شوند. برای لیست‌های طولانی قابل پیمایش از LazyColumn استفاده کنید.

آیا می‌توان Row را در Column و Column را در Row قرار داد؟

بله، تودرتو کردن Row/Column یک روش معمول است. با ترکیب دو کانتینر می‌توان شبکه‌های پیچیده‌ای ساخت. با این حال، از تودرتوی عمیق (4+ سطح) بدون نیاز خودداری کنید — این تعداد اندازه‌گیری‌های LayoutNode را افزایش می‌دهد و ترکیب‌بندی را کند می‌کند.

چگونه عرض یکسان همه عناصر در Column را تنظیم کنیم؟

از Modifier.fillMaxWidth() روی هر عنصر فرزند استفاده کنید. اگر Column دارای Modifier.fillMaxWidth() باشد، همه فرزندان با fillMaxWidth() تا تمام عرض کشیده می‌شوند. جایگزین: اگر Column در یک کانتینر ثابت قرار دارد، از Modifier.weight(1f) در ColumnScope استفاده کنید.

spacedBy در Column چگونه کار می‌کند؟

Arrangement.spacedBy(space) یک فاصله ثابت بین هر دو عنصر مجاور اضافه می‌کند. برخلاف SpaceBetween/SpaceAround، spacedBy عناصر را کش نمی‌دهد — فاصله ثابت است و فضای باقی‌مانده در انتهای Column می‌ماند. spacedBy قبل از اولین عنصر و بعد از آخرین عنصر فاصله اضافه نمی‌کند.

خلاصه

  • Column — کانتینر عمودی پایه Compose برای قرار دادن عناصر از بالا به پایین
  • Arrangement توزیع فضا را مدیریت می‌کند (Top، Center، SpaceBetween، spacedBy)
  • Alignment تراز افقی هر عنصر فرزند را تنظیم می‌کند
  • Weight فضای آزاد را به نسبت بین عناصر توزیع می‌کند
  • Column در مقابل LazyColumn: Column برای 3-10 عنصر، LazyColumn برای لیست‌های طولانی
  • IntrinsicSize به Column امکان می‌دهد ارتفاع را با حداقل اندازه فرزندان تنظیم کند
  • توصیه: برای فاصله بین عناصر به جای padding روی هر عنصر از spacedBy استفاده کنید

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

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

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

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