Column — یک کامپوننت Composable داخلی Jetpack Compose از بسته compose.foundation.layout است که عناصر فرزند را به صورت عمودی و یکی پس از دیگری قرار میدهد. Column معادل LinearLayout با جهت عمودی از سیستم View قدیمی است، اما برخلاف آن از توصیف اعلانی استفاده میکند و به طور خودکار به تغییرات وضعیت واکنش نشان میدهد. به گفته Google Android Developers, 2026، Column یکی از سه کانتینر پایه همراه با Row و Box است.
نکات اصلی
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 قرار میدهد.
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 محاسبه کند.
@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 | فاصلههای مساوی بین عناصر، نصف در لبهها |
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 نادیده گرفته میشود.
@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 همه عناصر فرزند را بلافاصله نمایش میدهد. اگر عناصر بیشتر از 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 پشتیبانی میکند.
| معیار | Column | LazyColumn |
|---|---|---|
| تعداد عناصر | تا 10-15 | هر تعداد |
| عملکرد | همیشه همه را رندر میکند | فقط قابل مشاهده + buffer |
| Scrolling | از طریق Modifier.verticalScroll | داخلی |
| IntrinsicSize | پشتیبانی میکند | پشتیبانی نمیکند |
| هدرهای چسبنده | خیر (شبیهسازی) | بله (stickyHeader) |
| انیمیشن عناصر | بدون انیمیشن داخلی | animateItemPlacement |
صفحه پروفایل کاربر را در نظر بگیرید، جایی که Column به عنوان کانتینر اصلی برای آواتار، نام، بیو و دکمههای عملیات استفاده میشود. در اینجا Column با IntrinsicSize.Min خود را با محتوا تنظیم میکند و weight برای توزیع فضا بین بخشها استفاده میشود.
@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 همه عناصر فرزند را بلافاصله رندر میکند که با 100+ عنصر باعث کاهش FPS میشود. LazyColumn فقط عناصر قابل مشاهده + بافر (معمولاً 3-5 صفحه) را رندر میکند. برای صفحههای ایستا با 3-10 عنصر، Column سریعتر است زیرا سربار مجازیسازی ندارد.
Modifier.verticalScroll(rememberScrollState()) را به Column اضافه کنید. این کار Column را قابل پیمایش میکند، اما مجازیسازی ارائه نمیدهد — همه عناصر همچنان بلافاصله رندر میشوند. برای لیستهای طولانی قابل پیمایش از LazyColumn استفاده کنید.
بله، تودرتو کردن Row/Column یک روش معمول است. با ترکیب دو کانتینر میتوان شبکههای پیچیدهای ساخت. با این حال، از تودرتوی عمیق (4+ سطح) بدون نیاز خودداری کنید — این تعداد اندازهگیریهای LayoutNode را افزایش میدهد و ترکیببندی را کند میکند.
از Modifier.fillMaxWidth() روی هر عنصر فرزند استفاده کنید. اگر Column دارای Modifier.fillMaxWidth() باشد، همه فرزندان با fillMaxWidth() تا تمام عرض کشیده میشوند. جایگزین: اگر Column در یک کانتینر ثابت قرار دارد، از Modifier.weight(1f) در ColumnScope استفاده کنید.
Arrangement.spacedBy(space) یک فاصله ثابت بین هر دو عنصر مجاور اضافه میکند. برخلاف SpaceBetween/SpaceAround، spacedBy عناصر را کش نمیدهد — فاصله ثابت است و فضای باقیمانده در انتهای Column میماند. spacedBy قبل از اولین عنصر و بعد از آخرین عنصر فاصله اضافه نمیکند.
خلاصه
ما یک اپلیکیشن موبایل به صورت کلید در دست توسعه خواهیم داد
IT Sectr از سال 2017 برنامههای iOS و Android را برای استارتاپها و کسبوکارها ایجاد میکند. ما به شما مشاوره میدهیم و بهترین راهحل را پیشنهاد خواهیم کرد.
همچنین بخوانید