Jetpack Compose è un moderno framework UI dichiarativo di Google per lo sviluppo Android, rilasciato nella versione stabile 1.0 a luglio 2021. Compose sostituisce il layout XML imperativo e il sistema View con funzioni Kotlin annotate con @Composable. Secondo Google I/O (2025), Compose è utilizzato nel 55% dei nuovi progetti Android e la dimensione media del codice UI si riduce del 30–50% rispetto a XML. Il framework ridisegna automaticamente solo le parti modificate dello schermo quando lo State cambia, eliminando le chiamate manuali a notifyDataSetChanged o findViewById.
Punti chiave
Jetpack Compose è un framework UI di Google costruito sui principi della programmazione reattiva. Invece di Activity con layout XML, FragmentManager e ViewBinding, lo sviluppatore descrive l'interfaccia tramite funzioni Kotlin annotate con @Composable. Compose non utilizza LayoutInflater — l'UI è composta da funzioni Kotlin pure compilate in bytecode. Il framework è composto da diverse librerie: Compose UI (componenti di base Text, Button, Column, Row), Compose Foundation (Material Design, Gestures, Focus), Compose Material3 (Material You con Dynamic Colors) e Compose Runtime (State, Side Effects, Coroutines). Compose funziona su Android API 21+ (Android 5.0) ed è completamente compatibile con il codice View/XML esistente tramite ComposeView — un adattatore AndroidView.
View System (2008) utilizza una gerarchia di oggetti View con gestione manuale: lo sviluppatore crea un layout XML, trova le Views tramite findViewById, implementa un Adapter per RecyclerView e chiama notifyDataSetChanged quando i dati cambiano. Compose descrive l'UI funzionalmente: quando lo stato cambia, il framework ricompone solo le funzioni Composable modificate, calcola il diff e applica modifiche minime alla Canvas. Le prestazioni di Compose sono paragonabili a View System e, in scenari con elenchi complessi (LazyColumn), spesso supera RecyclerView saltando elementi non necessari tramite il parametro key. In IT Sectr, Compose viene utilizzato per i nuovi moduli di applicazioni Android con minSdk 24+.
@Composable — un'annotazione che trasforma una normale funzione Kotlin in un elemento costitutivo dell'UI. Le funzioni Composable possono chiamare altre funzioni Composable, formando un albero di componenti. A differenza di View, le funzioni Composable non hanno stato per impostazione predefinita — sono stateless e vengono ridisegnate a ogni modifica dei parametri di input o dello State. Il Compose Compiler trasforma le funzioni @Composable in codice che può essere interrotto e ripreso (positional memoization) — ciò consente a Compose di riavviare solo le parti modificate senza ricostruire completamente l'albero.
import androidx.compose.foundation.layout.*
import androidx.compose.material3.*
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
@Composable
fun UserProfile(name: String, avatarUrl: String) {
Row(
modifier = Modifier
.fillMaxWidth()
.padding(16.dp),
verticalAlignment = Alignment.CenterVertically
) {
AsyncImage(
model = avatarUrl,
contentDescription = "User avatar",
modifier = Modifier.size(48.dp)
)
Spacer(modifier = Modifier.width(12.dp))
Text(
text = name,
style = MaterialTheme.typography.titleMedium
)
}
}La funzione UserProfile accetta name e avatarUrl come parametri, costruisce una riga con un avatar e un nome. Modifier.fillMaxWidth() allunga il componente a tutta larghezza, .padding(16.dp) aggiunge imbottitura. MaterialTheme.typography.titleMedium utilizza lo stile di sistema Material 3. Quando i parametri name o avatarUrl cambiano, Compose ricompone UserProfile — ricreando il componente con nuovi valori.
State in Compose è qualsiasi valore il cui cambiamento attiva la ricomposizione (riavvio) delle funzioni @Composable dipendenti. L'approccio di base è mutableStateOf(), che crea un MutableState<T> con supporto del sistema di snapshot di Compose. Snapshot è un meccanismo di tracciamento delle modifiche: quando si scrive in State, Compose segna lo Snapshot corrente come dirty e lo scheduler di ricomposizione riavvia solo le funzioni Composable che leggono quello State. Per le raccolte osservabili utilizzare mutableStateListOf() e mutableStateMapOf(). Compose supporta State da componenti Lifecycle-Aware tramite collectAsState() per Kotlin Flow e observeAsState() per LiveData.
@Composable
fun LikeButton() {
var liked by remember { mutableStateOf(false) }
var count by remember { mutableStateOf(42) }
Button(
onClick = {
liked = !liked
if (liked) count++ else count--
},
colors = ButtonDefaults.buttonColors(
containerColor = if (liked) MaterialTheme.colorScheme.primary
else MaterialTheme.colorScheme.surfaceVariant
)
) {
Text("♥ $count")
}
}Il codice crea un pulsante "Like" con stato liked (Boolean) e count (Int) memorizzati tramite mutableStateOf(). Alla pressione, liked viene invertito e il contatore aumenta/diminuisce — Compose ricompone LikeButton automaticamente. Il delegato by consente di utilizzare State come una variabile normale: liked = !liked invece di liked.value = !liked.value. Il colore del pulsante cambia reattivamente tra primary (piaciuto) e surfaceVariant (non piaciuto).
remember — una funzione di Compose che memorizza nella cache un valore tra le ricomposizioni. Senza remember, ogni riavvio di una funzione Composable crea un nuovo stato (mutableStateOf) — ciò rompe la logica dell'applicazione: alla rotazione dello schermo o al cambiamento dello State padre, il contatore si resetta. remember accetta un lambda di calcolo e valuta il valore solo alla prima composizione; nelle successive restituisce il risultato memorizzato nella cache. Per resettare la cache utilizzare remember(key) — la chiave determina quando ricalcolare il valore. remember(key1, key2) ricalcola quando qualsiasi chiave cambia. Per stati di lunga durata (che sopravvivono alla rotazione dello schermo) utilizzare rememberSaveable — un analogo di remember con salvataggio in Bundle tramite SavedStateHandle.
@Composable
fun TimerScreen() {
var seconds by rememberSaveable { mutableStateOf(0) }
LaunchedEffect(Unit) {
while (true) {
delay(1000)
seconds++
}
}
Column(
modifier = Modifier.fillMaxSize().padding(32.dp),
horizontalAlignment = Alignment.CenterHorizontally
) {
Text(
text = "Elapsed: ${seconds}s",
style = MaterialTheme.typography.displayMedium
)
}
}rememberSaveable preserva seconds alla rotazione dello schermo (cambiamento di configurazione). LaunchedEffect avvia una coroutine che incrementa seconds ogni secondo. Alla ricomposizione di TimerScreen (ogni secondo) seconds non viene resettato grazie a rememberSaveable. Utilizzare remember normale per gli stati che non devono sopravvivere ai cambiamenti di configurazione (ad esempio, flag di animazione).
Modifier — un oggetto contenitore immutabile che implementa il pattern Builder per configurare l'aspetto, il comportamento e il layout dei componenti Composable. Ogni chiamata al metodo Modifier (.padding(), .width(), .clickable(), .background()) restituisce un nuovo Modifier con l'elemento aggiunto. L'ordine dei modificatori è importante: .padding(16.dp).clickable { } — l'imbottitura viene applicata prima del gestore di click, clickable traccia l'intera area inclusa l'imbottitura. .clickable { }.padding(16.dp) — l'intera area prima dell'imbottitura è cliccabile, l'imbottitura sposta il contenuto verso l'interno. Modifier supporta implementazioni personalizzate tramite then(otherModifier) e compositionLocal per accedere alle impostazioni padre.
@Composable
fun CardExample() {
Card(
modifier = Modifier
.fillMaxWidth()
.padding(16.dp)
.clickable { println("Card clicked") },
elevation = CardDefaults.cardElevation(defaultElevation = 4.dp),
colors = CardDefaults.cardColors(
containerColor = MaterialTheme.colorScheme.surfaceVariant
)
) {
Column(modifier = Modifier.padding(16.dp)) {
Text("Jetpack Compose", style = MaterialTheme.typography.titleLarge)
Spacer(modifier = Modifier.height(8.dp))
Text(
"UI dichiarativa per Android con State e Modifier",
style = MaterialTheme.typography.bodyMedium
)
}
}
}CardExample dimostra la catena Modifier: fillMaxWidth + padding + clickable. Card è un componente Material3 con le proprie impostazioni di elevation e colors. Il Column annidato ha un'imbottitura interna di 16dp. Compose Material3 adatta automaticamente i colori a Dynamic Color (Material You) su Android 12+. Card è uno dei 30+ componenti Material3 integrati in Compose.
State hoisting — un pattern di sollevamento dello stato da una funzione Composable al suo chiamante, rendendo la funzione stateless. Un componente stateless riceve dati e callback tramite parametri senza possedere State autonomamente. Ciò migliora la riutilizzabilità e la testabilità: il componente può essere chiamato con diversi States e testato in preview. Google raccomanda l'architettura: ViewModel + StateFlow (o MutableStateFlow) + collectAsState() in Compose. ViewModel solleva lo stato a livello di schermo, Compose lo renderizza. Gli effetti collaterali (LaunchedEffect, DisposableEffect) gestiscono eventi una tantum.
| Componente | Responsabilità | Tecnologia |
|---|---|---|
| ViewModel | Archiviazione State, logica di business | StateFlow, MutableStateFlow |
| Screen Composable | Organizzazione schermo, State hoisting | collectAsState(), Scaffold, LazyColumn |
| Stateless Component | UI senza stato, rendering puro | Parametri @Composable + lambda |
| Side Effect | Azioni una tantum (snackbar, navigazione) | LaunchedEffect, SnackbarHostState |
Domande frequenti
Il layout XML è imperativo: LayoutInflater carica XML, findViewById trova Views, lo sviluppatore aggiorna manualmente testo/elenchi. Compose è dichiarativo: l'UI è descritta da funzioni Kotlin @Composable e il framework ridisegna automaticamente solo le parti modificate quando State cambia. Compose riduce il volume di codice UI del 30–50% e non utilizza XML.
Sì, Google fornisce Navigation Compose — una libreria per la navigazione dichiarativa tra schermate. NavController gestisce lo stack delle route, composable() registra le schermate, navArgument passa parametri. Alternative: Voyager (community) e Decompose (Badoo). Navigation Compose è lo standard ufficiale con supporto per deep link e argomenti type-safe.
Modifier è un contenitore immutabile di pattern decorativi (padding, size, clickable, background, border, clip) applicati ai componenti Composable. Ogni chiamata restituisce un nuovo Modifier con l'elemento aggiunto. L'ordine è importante: .padding().clickable() applica l'imbottitura prima del clic, .clickable().padding() — il contrario. Modifier è il modo principale per personalizzare i componenti Compose.
Jetpack Compose supporta Android API 21+ (Android 5.0 Lollipop) tramite Compose Compiler e Compose BOM. Material 3 (Dynamic Colors) è disponibile su Android 12+; sulle versioni precedenti viene utilizzata una palette di fallback. Per i nuovi progetti, Google raccomanda minSdk 24+ (Android 7.0), che è completamente coperto da Compose.
Google fornisce Compose UI Test — una libreria per test su JVM (Desktop) ed emulatore. Funzioni principali: composeTestRule.setContent { } per renderizzare un componente, onNodeWithText() per trovare elementi, performClick()/performTextInput() per azioni. I test Espresso sono compatibili con Compose tramite ComposeTestRule, ma Compose UI Test è l'approccio preferito e più veloce.
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