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 от височината (тегло 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, идентичност базирана на ключ, анимация на добавяне/премахване (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 се използва като основен контейнер за аватар, име, био и бутони за действия. Тук 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 рендерира само видимите елементи + 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 г. Ще ви консултираме и ще предложим най-доброто решение.
Прочетете също