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 weight: розподіл простору між елементами

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 ігнорується.

kotlin
@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 vs LazyColumn: коли що використовувати

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.

КритерійColumnLazyColumn
Кількість елементівДо 10-15Будь-яке
ПродуктивністьЗавжди рендерить всіЛише видимі + buffer
ScrollingЧерез Modifier.verticalScrollВбудований
IntrinsicSizeПідтримуєНе підтримує
Sticky headersНі (емуляція)Так (stickyHeader)
Анімація елементівНемає вбудованоїanimateItemPlacement

Практичні приклади використання Column

Розглянемо екран профілю користувача, де Column використовується як основний контейнер для аватарки, імені, bio та кнопок дій. Тут 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)
            // 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 відрізняється від LazyColumn за продуктивністю?

Column рендерить всі дочірні елементи одразу, що при 100+ елементах викликає падіння FPS. LazyColumn рендерить лише видимі елементи + buffer (зазвичай 3-5 екранів). Для статичних екранів з 3-10 елементами Column швидше, оскільки немає overhead віртуалізації.

Як зробити Column прокручуваною?

Додайте Modifier.verticalScroll(rememberScrollState()) до Column. Це робить Column скролованою, але не дає віртуалізації — всі елементи, як і раніше, рендеряться одразу. Для довгих скролованих списків використовуйте LazyColumn.

Чи можна вкласти Row в Column і Column в Row?

Так, вкладеність Row/Column — нормальна практика. Комбінуючи два контейнери, можна будувати складні сітки. Однак уникайте глибокої вкладеності (4+ рівні) без необхідності — це збільшує кількість вимірювань LayoutNode і сповільнює композицію.

Як зробити однакову ширину всіх елементів в Column?

Використовуйте Modifier.fillMaxWidth() на кожному дочірньому елементі. Якщо Column має Modifier.fillMaxWidth(), всі дочірні з fillMaxWidth() розтягнуться на всю ширину. Альтернатива: Modifier.weight(1f) в ColumnScope, якщо Column знаходиться у фіксованому контейнері.

Як працює spacedBy в Column?

Arrangement.spacedBy(space) додає фіксований відступ між кожними двома сусідніми елементами. На відміну від SpaceBetween/SpaceAround, spacedBy не розтягує елементи — відступ фіксований, а решта простору залишається в кінці Column. spacedBy не додає відступ перед першим і після останнього елемента.

Підсумки

  • Column — базовий вертикальний контейнер Compose для розміщення елементів зверху вниз
  • Arrangement керує розподілом простору (Top, Center, SpaceBetween, spacedBy)
  • Alignment задає горизонтальне вирівнювання кожного дочірнього елемента
  • Weight розподіляє вільний простір пропорційно між елементами
  • Column vs LazyColumn: Column для 3-10 елементів, LazyColumn для довгих списків
  • IntrinsicSize дозволяє Column підлаштовувати висоту під мінімальне вимірювання дочірніх
  • Рекомендація: використовуйте spacedBy для відступів між елементами замість padding на кожному

Ми розробимо мобільний застосунок під ключ

IT Sectr створює застосунки для iOS та Android для стартапів і бізнесу з 2017 року. Ми проконсультуємо вас і запропонуємо найкраще рішення.

Обговорити проект

Читайте також