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 — елемент займає лише свою intrinsic-висоту, а решта простору залишається порожньою. Це корисно, коли елемент повинен бути притиснутий до однієї сторони, але weight задає лише пропорцію розподілу порожнього місця.
Обмеження weight: weight працює лише в Column з фіксованою висотою або fillMaxHeight(). Якщо висота Column визначена дочірніми елементами (wrap content), ваги не мають сенсу — немає вільного простору для розподілу. Також weight не можна комбінувати з Modifier.height() на тому ж елементі — вони конфліктують, і weight ігнорується.
@Composable
fun WeightedColumn() {
Column(
modifier = Modifier.fillMaxHeight().width(300.dp)
) {
// Займає 1/6 висоти (weight 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 дає: item caching, key-based identity, анімацію додавання/видалення (animateItemPlacement), sticky headers. Якщо список містить елементи різного типу (різні viewType) — використовуйте LazyColumn з sealed class в items. Column не підтримує sticky headers (їх потрібно емулювати через scrollable Column). Також LazyColumn підтримує LazyVerticalGrid при використанні GridCells.
| Критерій | Column | LazyColumn |
|---|---|---|
| Кількість елементів | До 10-15 | Будь-яке |
| Продуктивність | Завжди рендерить всі | Лише видимі + buffer |
| Scrolling | Через Modifier.verticalScroll | Вбудований |
| IntrinsicSize | Підтримує | Не підтримує |
| Sticky headers | Ні (емуляція) | Так (stickyHeader) |
| Анімація елементів | Немає вбудованої | animateItemPlacement |
Розглянемо екран профілю користувача, де Column використовується як основний контейнер для аватарки, імені, bio та кнопок дій. Тут 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)
// Bio
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 центрує аватарку, ім'я та bio. Row всередині Column — вкладений контейнер для кнопок в один рядок. Така комбінація Column (вертикальне розташування) та Row (горизонтальне) — типовий патерн побудови UI в Compose.
Часті запитання
Column рендерить всі дочірні елементи одразу, що при 100+ елементах викликає падіння FPS. LazyColumn рендерить лише видимі елементи + buffer (зазвичай 3-5 екранів). Для статичних екранів з 3-10 елементами Column швидше, оскільки немає overhead віртуалізації.
Додайте Modifier.verticalScroll(rememberScrollState()) до Column. Це робить Column скролованою, але не дає віртуалізації — всі елементи, як і раніше, рендеряться одразу. Для довгих скролованих списків використовуйте LazyColumn.
Так, вкладеність Row/Column — нормальна практика. Комбінуючи два контейнери, можна будувати складні сітки. Однак уникайте глибокої вкладеності (4+ рівні) без необхідності — це збільшує кількість вимірювань LayoutNode і сповільнює композицію.
Використовуйте Modifier.fillMaxWidth() на кожному дочірньому елементі. Якщо Column має Modifier.fillMaxWidth(), всі дочірні з fillMaxWidth() розтягнуться на всю ширину. Альтернатива: Modifier.weight(1f) в ColumnScope, якщо Column знаходиться у фіксованому контейнері.
Arrangement.spacedBy(space) додає фіксований відступ між кожними двома сусідніми елементами. На відміну від SpaceBetween/SpaceAround, spacedBy не розтягує елементи — відступ фіксований, а решта простору залишається в кінці Column. spacedBy не додає відступ перед першим і після останнього елемента.
Підсумки
Ми розробимо мобільний застосунок під ключ
IT Sectr створює застосунки для iOS та Android для стартапів і бізнесу з 2017 року. Ми проконсультуємо вас і запропонуємо найкраще рішення.
Читайте також