Column — este un component Composable încorporat Jetpack Compose din pachetul compose.foundation.layout, care aranjează elementele copil vertical, unul sub altul. Column este analogul lui LinearLayout cu orientare verticală din vechiul sistem View, dar spre deosebire de acesta utilizează descrierea declarativă și reacționează automat la modificările de stare. Conform Google Android Developers, 2026, Column este unul dintre cele trei containere de bază împreună cu Row și Box.
Principalele
Column — este o funcție Composable care acceptă parametri opționali: modifier, verticalArrangement, horizontalAlignment și content — o lambda cu ColumnScope. În interiorul Column, funcțiile Composable copil sunt aranjate de sus în jos în ordinea declarării. Înălțimea Column este egală cu suma înălțimilor elementelor copil plus spațiul specificat de Arrangement. Lățimea — după lățimea maximă a elementului copil ținând cont de Alignment.
Column este un container invizibil: nu are propriul fundal sau margine în mod implicit. Dacă este necesar fundal — adăugați Modifier.background() la Column însăși. Spre deosebire de LazyColumn, Column afișează toate elementele copil simultan și nu suportă virtualizarea. Aceasta înseamnă că Column este potrivită doar pentru seturi mici de date — până la 10-15 elemente. Pentru liste lungi utilizați LazyColumn.
ColumnScope — este un receiver pentru lambda content a Column. Acesta oferă modificatori suplimentari care funcționează doar în interiorul Column: weight(), align(), alignByBaseline(). Acești modificatori nu au sens în afara Column, deoarece se bazează pe specificul aranjării verticale. De exemplu, Modifier.align(Alignment.CenterHorizontally) aliniază elementul copil la centrul Column pe orizontală.
VerticalArrangement determină cum se distribuie spațiul vertical între elemente. Valorile disponibile: Arrangement.Top (implicit), Bottom, Center, SpaceBetween, SpaceEvenly, SpaceAround. Dacă înălțimea Column este mai mare decât suma înălțimilor elementelor, Arrangement distribuie spațiul liber. Dacă elementele ocupă toată înălțimea — Arrangement nu are efect.
HorizontalAlignment stabilește alinierea orizontală a fiecărui element copil. Alignment.Start (implicit, LTR), CenterHorizontally, End. Alignment acționează asupra fiecărui element independent: dacă un element este îngust, iar altul lat — primul va fi aliniat, al doilea poate depăși limitele Column. Alignment funcționează doar dacă Column are lățime fixă sau fillMaxWidth.
Modifier pentru Column: Column acceptă Modifier care se aplică containerului însuși. Modifier.fillMaxWidth(), fillMaxHeight(), size(), padding() — toți modificatorii standard funcționează. Particularitate: Modifier.height(IntrinsicSize.Min) forțează Column să calculeze înălțimea minimă pe baza elementelor copil ținând cont de Intrinsic measurement.
@Composable
fun ColumnArrangementDemo() {
Column(
modifier = Modifier.fillMaxSize().background(Color(0xFFF5F5F5)),
verticalArrangement = Arrangement.SpaceEvenly,
horizontalAlignment = Alignment.CenterHorizontally
) {
Text("Sus", modifier = Modifier.background(Color.Cyan))
Text("Mijloc", modifier = Modifier.background(Color.Magenta))
Text("Jos", modifier = Modifier.background(Color.Yellow))
}
}
// IntrinsicSize: Column ajustează înălțimea la conținut
@Composable
fun IntrinsicColumn() {
Column(
modifier = Modifier
.height(IntrinsicSize.Min)
.width(200.dp)
) {
Text("Text scurt")
Text("Un text foarte lung care se va împacheta în coloană")
}
}
| Arrangement | Comportament |
|---|---|
| Arrangement.Top | Elementele lipite de sus, spațiul liber în jos |
| Arrangement.Center | Elementele în centru, spațiul împărțit egal sus și jos |
| Arrangement.SpaceBetween | Primul element sus, ultimul jos, restul uniform |
| Arrangement.SpaceEvenly | Spații egale între toate elementele și margini |
| Arrangement.SpaceAround | Spații egale între elemente, jumătate la margini |
Modifier.weight() — este un modificator ColumnScope care distribuie spațiul vertical liber între elementele Column proporțional cu greutățile specificate. Dacă Column ocupă 400dp înălțime, iar elementele copil în total — 100dp, atunci restul de 300dp se împarte între elementele weight. Elementul cu weight(2f) va primi de două ori mai mult spațiu decât elementul cu weight(1f).
fill — al doilea parametru weight: weight(weight: Float, fill: Boolean = true). Dacă fill = true (implicit), elementul se întinde pe toată înălțimea disponibilă. Dacă fill = false — elementul ocupă doar înălțimea sa intrinsecă, iar spațiul rămas rămâne gol. Acest lucru este util când elementul trebuie lipit de o parte, dar weight stabilește doar proporția de distribuție a spațiului gol.
Limitările weight: weight funcționează doar în Column cu înălțime fixă sau fillMaxHeight(). Dacă înălțimea Column este determinată de elementele copil (wrap content), greutățile nu au sens — nu există spațiu liber de distribuit. De asemenea, weight nu poate fi combinat cu Modifier.height() pe același element — ele intră în conflict, iar weight este ignorat.
@Composable
fun WeightedColumn() {
Column(
modifier = Modifier.fillMaxHeight().width(300.dp)
) {
// Ocupă 1/6 din înălțime (greutate 1 din suma 1+2+3=6)
Box(
modifier = Modifier
.weight(1f)
.fillMaxWidth()
.background(Color.Red)
)
// Ocupă 2/6 din înălțime
Box(
modifier = Modifier
.weight(2f)
.fillMaxWidth()
.background(Color.Green)
)
// Ocupă 3/6 din înălțime
Box(
modifier = Modifier
.weight(3f)
.fillMaxWidth()
.background(Color.Blue)
)
}
}
Column afișează toate elementele copil imediat. Dacă elementele sunt mai mult de 10-15, Column creează o sarcină semnificativă asupra compoziției și măsurării. LazyColumn, dimpotrivă, render-ează doar elementele vizibile și reutilizează elementele invizibile. Pentru liste lungi, liste cu mii de elemente, liste infinite sau chat-uri — LazyColumn este obligatoriu.
Când Column este mai bună: ecrane cu formulare (3-10 câmpuri), carduri de profil, coloane verticale cu pictograme, meniuri. Column suportă și IntrinsicSize, util pentru înălțime adaptivă. În plus, Column este mai simplu de depanat — nu are virtualizare, toate elementele sunt vizibile în Layout Inspector. Pentru UI static, Column este alegerea corectă.
LazyColumn oferă: item caching, identitate bazată pe cheie, animație de adăugare/ștergere (animateItemPlacement), sticky headers. Dacă lista conține elemente de tipuri diferite (viewType diferit) — utilizați LazyColumn cu sealed class în items. Column nu suportă sticky headers (trebuie emulate prin scrollable Column). De asemenea, LazyColumn suportă LazyVerticalGrid când se utilizează GridCells.
| Criteriu | Column | LazyColumn |
|---|---|---|
| Număr de elemente | Până la 10-15 | Oricât |
| Performanță | Render-ează întotdeauna toate | Doar vizibile + buffer |
| Scrolling | Prin Modifier.verticalScroll | Încorporat |
| IntrinsicSize | Suportă | Nu suportă |
| Sticky headers | Nu (emulare) | Da (stickyHeader) |
| Animație elemente | Fără animație încorporată | animateItemPlacement |
Să analizăm ecranul profilului de utilizator, unde Column este utilizat ca container principal pentru avatar, nume, bio și butoane de acțiuni. Aici Column cu IntrinsicSize.Min se ajustează la conținut, iar weight se aplică pentru distribuirea spațiului între secțiuni.
@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)
) {
// Avatar
Icon(
imageVector = Icons.Default.AccountCircle,
contentDescription = "Avatar",
modifier = Modifier.size(64.dp)
)
// Nume
Text(name, style = MaterialTheme.typography.headlineSmall)
// Bio
Text(bio, style = MaterialTheme.typography.bodyMedium,
modifier = Modifier.padding(top = 4.dp))
// Butoane de acțiuni
Row(
horizontalArrangement = Arrangement.spacedBy(12.dp),
modifier = Modifier.padding(top = 12.dp)
) {
Button(onClick = { }) { Text("Mesaj") }
OutlinedButton(onClick = { }) { Text("Urmărește") }
}
}
}
}
În exemplu, Column utilizează Arrangement.spacedBy(8.dp) pentru spații uniforme între elemente. horizontalAlignment = CenterHorizontally centrează avatarul, numele și bio. Row în interiorul Column — container imbricat pentru butoane într-un rând. Această combinație de Column (aranjare verticală) și Row (aranjare orizontală) este un model tipic de construire a UI în Compose.
Întrebări frecvente
Column render-ează toate elementele copil imediat, ceea ce la 100+ elemente cauzează scăderea FPS. LazyColumn render-ează doar elementele vizibile + buffer (de obicei 3-5 ecrane). Pentru ecrane statice cu 3-10 elemente, Column este mai rapidă, deoarece nu are overhead de virtualizare.
Adăugați Modifier.verticalScroll(rememberScrollState()) la Column. Aceasta face Column derulabilă, dar nu oferă virtualizare — toate elementele se render-ează în continuare imediat. Pentru liste lungi derulabile utilizați LazyColumn.
Da, îmbricarea Row/Column este o practică normală. Combinând două containere, se pot construi grile complexe. Totuși, evitați îmbricarea profundă (4+ niveluri) fără necesitate — aceasta crește numărul de măsurători LayoutNode și încetinește compoziția.
Utilizați Modifier.fillMaxWidth() pe fiecare element copil. Dacă Column are Modifier.fillMaxWidth(), toate elementele copil cu fillMaxWidth() se vor întinde pe toată lățimea. Alternativă: Modifier.weight(1f) în ColumnScope, dacă Column se află într-un container fix.
Arrangement.spacedBy(space) adaugă un spațiu fix între fiecare două elemente adiacente. Spre deosebire de SpaceBetween/SpaceAround, spacedBy nu întinde elementele — spațiul este fix, iar restul spațiului rămâne la sfârșitul Column. spacedBy nu adaugă spațiu înaintea primului element și după ultimul element.
Concluzii
Vom dezvolta o aplicație mobilă la cheie
IT Sectr creează aplicații iOS și Android pentru startup-uri și afaceri din 2017. Vă vom consilia și vă vom propune cea mai bună soluție.
Citiți și