Column è un componente Composable integrato di Jetpack Compose del pacchetto compose.foundation.layout che dispone gli elementi figli verticalmente, uno sotto l'altro. Column è l'equivalente di LinearLayout con orientamento verticale del vecchio sistema View, ma a differenza di questo, utilizza una descrizione dichiarativa e reagisce automaticamente ai cambiamenti di stato. Secondo Google Android Developers, 2026, Column è uno dei tre contenitori di base insieme a Row e Box.
Punti chiave
Column è una funzione Composable che accetta parametri opzionali: modifier, verticalArrangement, horizontalAlignment e content — una lambda con ColumnScope. All'interno di Column, le funzioni Composable figlie vengono disposte dall'alto verso il basso nell'ordine di dichiarazione. L'altezza di Column è uguale alla somma delle altezze dei figli più lo spazio specificato da Arrangement. La larghezza è uguale alla larghezza massima del figlio considerando Alignment.
Column è un contenitore invisibile: non ha sfondo o bordo predefiniti. Se serve uno sfondo, aggiungi Modifier.background() alla Column stessa. A differenza di LazyColumn, Column rende tutti gli elementi figli simultaneamente e non supporta la virtualizzazione. Ciò significa che Column è adatta solo a set di dati piccoli — fino a 10-15 elementi. Per elenchi lunghi, usa LazyColumn.
ColumnScope è il receiver del lambda content di Column. Fornisce modificatori aggiuntivi che funzionano solo all'interno di Column: weight(), align(), alignByBaseline(). Questi modificatori non hanno senso al di fuori di Column perché si basano sulle specificità del layout verticale. Ad esempio, Modifier.align(Alignment.CenterHorizontally) allinea un elemento figlio al centro di Column orizzontalmente.
VerticalArrangement determina come lo spazio verticale viene distribuito tra gli elementi. Valori disponibili: Arrangement.Top (predefinito), Bottom, Center, SpaceBetween, SpaceEvenly, SpaceAround. Se l'altezza di Column è maggiore della somma delle altezze degli elementi, Arrangement distribuisce lo spazio libero. Se gli elementi occupano tutta l'altezza, Arrangement non ha effetto.
HorizontalAlignment imposta l'allineamento orizzontale di ogni elemento figlio. Alignment.Start (predefinito per LTR), CenterHorizontally, End. Alignment agisce su ogni elemento indipendentemente: se un elemento è stretto e un altro è largo, il primo verrà allineato, il secondo potrebbe superare i limiti di Column. Alignment funziona solo se Column ha una larghezza fissa o fillMaxWidth.
Modifier per Column: Column accetta un Modifier che si applica al contenitore stesso. Modifier.fillMaxWidth(), fillMaxHeight(), size(), padding() — tutti i modificatori standard funzionano. Nota speciale: Modifier.height(IntrinsicSize.Min) forza Column a calcolare l'altezza minima basata sugli elementi figli utilizzando la misurazione Intrinsic.
@Composable
fun ColumnArrangementDemo() {
Column(
modifier = Modifier.fillMaxSize().background(Color(0xFFF5F5F5)),
verticalArrangement = Arrangement.SpaceEvenly,
horizontalAlignment = Alignment.CenterHorizontally
) {
Text("Su", modifier = Modifier.background(Color.Cyan))
Text("Medio", modifier = Modifier.background(Color.Magenta))
Text("Giù", modifier = Modifier.background(Color.Yellow))
}
}
// IntrinsicSize: Column adatta l'altezza al contenuto
@Composable
fun IntrinsicColumn() {
Column(
modifier = Modifier
.height(IntrinsicSize.Min)
.width(200.dp)
) {
Text("Testo corto")
Text("Un testo molto lungo che verrà avvolto all'interno della colonna")
}
}
| Arrangement | Comportamento |
|---|---|
| Arrangement.Top | Elementi attaccati in alto, spazio libero in basso |
| Arrangement.Center | Elementi centrati, spazio diviso equamente sopra e sotto |
| Arrangement.SpaceBetween | Primo elemento in alto, ultimo in basso, altri uniformemente |
| Arrangement.SpaceEvenly | Spazi uguali tra tutti gli elementi e i bordi |
| Arrangement.SpaceAround | Spazi uguali tra gli elementi, metà spazio ai bordi |
Modifier.weight() è un modificatore ColumnScope che distribuisce lo spazio verticale libero tra gli elementi di Column proporzionalmente ai pesi specificati. Se Column occupa 400dp di altezza e gli elementi figli totalizzano 100dp, i rimanenti 300dp vengono suddivisi tra gli elementi weight. Un elemento con weight(2f) riceve il doppio dello spazio rispetto a un elemento con weight(1f).
fill — il secondo parametro di weight: weight(weight: Float, fill: Boolean = true). Se fill = true (predefinito), l'elemento si estende per tutta l'altezza disponibile. Se fill = false, l'elemento occupa solo la sua altezza intrinseca e lo spazio rimanente resta vuoto. Questo è utile quando un elemento deve essere attaccato a un lato ma weight definisce solo la proporzione di distribuzione dello spazio vuoto.
Limitazioni di weight: weight funziona solo in Column con altezza fissa o fillMaxHeight(). Se l'altezza di Column è determinata dagli elementi figli (wrap content), i pesi non hanno senso — non c'è spazio libero da distribuire. Inoltre, weight non può essere combinato con Modifier.height() sullo stesso elemento — entrano in conflitto e weight viene ignorato.
@Composable
fun WeightedColumn() {
Column(
modifier = Modifier.fillMaxHeight().width(300.dp)
) {
// Prende 1/6 dell'altezza (weight 1 di somma 1+2+3=6)
Box(
modifier = Modifier
.weight(1f)
.fillMaxWidth()
.background(Color.Red)
)
// Prende 2/6 dell'altezza
Box(
modifier = Modifier
.weight(2f)
.fillMaxWidth()
.background(Color.Green)
)
// Prende 3/6 dell'altezza
Box(
modifier = Modifier
.weight(3f)
.fillMaxWidth()
.background(Color.Blue)
)
}
}
Column rende tutti gli elementi figli immediatamente. Se ci sono più di 10-15 elementi, Column crea un carico significativo sulla composizione e misurazione. LazyColumn, al contrario, rende solo gli elementi visibili e riutilizza quelli invisibili. Per elenchi lunghi, elenchi con migliaia di elementi, elenchi infiniti o chat — LazyColumn è obbligatorio.
Quando Column è migliore: schermate con moduli (3-10 campi), carte profilo, colonne verticali con icone, menu. Column supporta anche IntrinsicSize, utile per l'altezza adattiva. Inoltre, Column è più facile da debuggare — nessuna virtualizzazione, tutti gli elementi sono visibili in Layout Inspector. Per UI statica, Column è la scelta giusta.
LazyColumn fornisce: caching degli elementi, identità basata su chiave, animazione di aggiunta/rimozione (animateItemPlacement), intestazioni sticky (sticky headers). Se l'elenco contiene elementi di tipo diverso (diversi viewType), usa LazyColumn con sealed class in items. Column non supporta sticky headers (devono essere emulati tramite Column scrollabile). Inoltre, LazyColumn supporta LazyVerticalGrid quando si usa GridCells.
| Criterio | Column | LazyColumn |
|---|---|---|
| Numero di elementi | Fino a 10-15 | Qualsiasi |
| Prestazioni | Rende sempre tutto | Solo visibili + buffer |
| Scrolling | Tramite Modifier.verticalScroll | Integrato |
| IntrinsicSize | Supportato | Non supportato |
| Sticky headers | No (emulazione) | Sì (stickyHeader) |
| Animazione elementi | Non integrata | animateItemPlacement |
Consideriamo una schermata di profilo utente dove Column viene usata come contenitore principale per avatar, nome, bio e pulsanti di azione. Qui, Column con IntrinsicSize.Min si adatta al contenuto e weight viene usato per distribuire lo spazio tra le sezioni.
@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)
)
// Nome
Text(name, style = MaterialTheme.typography.headlineSmall)
// Bio
Text(bio, style = MaterialTheme.typography.bodyMedium,
modifier = Modifier.padding(top = 4.dp))
// Pulsanti di azione
Row(
horizontalArrangement = Arrangement.spacedBy(12.dp),
modifier = Modifier.padding(top = 12.dp)
) {
Button(onClick = { }) { Text("Messaggio") }
OutlinedButton(onClick = { }) { Text("Segui") }
}
}
}
}
Nell'esempio, Column utilizza Arrangement.spacedBy(8.dp) per spaziatura uniforme tra gli elementi. horizontalAlignment = CenterHorizontally centra avatar, nome e bio. Il Row all'interno di Column è un contenitore annidato per i pulsanti in una riga. Questa combinazione di Column (disposizione verticale) e Row (disposizione orizzontale) è un modello tipico di costruzione dell'interfaccia in Compose.
Domande frequenti
Column rende tutti gli elementi figli in una volta, causando cali di FPS con 100+ elementi. LazyColumn rende solo gli elementi visibili più un buffer (di solito 3-5 schermate). Per schermate statiche con 3-10 elementi, Column è più veloce poiché non c'è overhead di virtualizzazione.
Aggiungi Modifier.verticalScroll(rememberScrollState()) a Column. Questo rende Column scrollabile ma non fornisce virtualizzazione — tutti gli elementi vengono comunque renderizzati in una volta. Per elenchi scrollabili lunghi, usa LazyColumn.
Sì, l'annidamento di Row/Column è una pratica comune. Combinando i due contenitori, si possono costruire griglie complesse. Tuttavia, evita annidamenti profondi (4+ livelli) senza necessità — aumenta il numero di misurazioni LayoutNode e rallenta la composizione.
Usa Modifier.fillMaxWidth() su ogni elemento figlio. Se Column ha Modifier.fillMaxWidth(), tutti i figli con fillMaxWidth() si estenderanno per tutta la larghezza. Alternativa: usa Modifier.weight(1f) in ColumnScope se Column si trova in un contenitore fisso.
Arrangement.spacedBy(space) aggiunge uno spazio fisso tra ogni due elementi adiacenti. A differenza di SpaceBetween/SpaceAround, spacedBy non allunga gli elementi — lo spazio è fisso e lo spazio rimanente resta alla fine di Column. spacedBy non aggiunge spazio prima del primo né dopo l'ultimo elemento.
Riepilogo
Svilupperemo un'applicazione mobile chiavi in mano
IT Sectr crea applicazioni iOS e Android per startup e aziende dal 2017. Ti consulteremo e ti proporremo la soluzione migliore.
Leggi anche