Jetpack Compose — framework-ul UI declarativ modern de la Google pentru dezvoltarea Android, lansat în versiunea stabilă 1.0 în iulie 2021. Compose înlocuiește marcarea XML imperativă și sistemul View cu funcții Kotlin cu adnotarea @Composable. Conform Google I/O (2025), Compose este folosit în 55% din proiectele noi pe Android, iar dimensiunea medie a codului UI se reduce cu 30–50% față de XML. Framework-ul redesenează automat doar părțile modificate ale ecranului la schimbarea State, eliminând apelarea manuală a notifyDataSetChanged sau findViewById.
Principal
Jetpack Compose — framework-ul UI Google construit pe principii de programare reactivă. În loc de Activity cu layout-uri XML, FragmentManager și ViewBinding, dezvoltatorul descrie interfața prin funcții Kotlin cu adnotarea @Composable. Compose nu folosește LayoutInflater — UI este format din funcții Kotlin pure, compilate în bytecode. Framework-ul constă din mai multe biblioteci: Compose UI (componente de bază Text, Button, Column, Row), Compose Foundation (Material Design, Gesturi, Focus), Compose Material3 (Material You cu Dynamic Colors) și Compose Runtime (State, Side Effects, Coroutines). Compose funcționează pe Android API 21+ (Android 5.0) și este complet compatibil cu codul existent pe View/XML prin ComposeView — adaptorul AndroidView.
View System (2008) utilizează o ierarhie de obiecte View cu gestionare manuală: dezvoltatorul creează un layout XML, găsește View prin findViewById, implementează Adapter pentru RecyclerView și apelează notifyDataSetChanged la modificarea datelor. Compose descrie UI funcțional: la modificarea stării, framework-ul repornește (recompose) doar funcțiile Composable modificate, calculează diff și aplică modificări minime la Canvas. Performanța Compose este comparabilă cu View System, iar în scenarii cu liste complexe (LazyColumn) deseori depășește RecyclerView prin omiterea elementelor inutile prin parametrul key. În IT Sectr, Compose este folosit pentru modulele noi ale aplicațiilor Android cu minSdk 24+.
@Composable — adnotarea care transformă o funcție obișnuită Kotlin într-un bloc de construcție UI. Funcțiile Composable pot apela alte funcții Composable, formând un arbore de componente. Spre deosebire de View, funcțiile Composable nu au stare implicit — sunt stateless și se redesenează la fiecare modificare a parametrilor de intrare sau a State. Compilatorul (Compose Compiler) transformă funcțiile @Composable în cod care poate fi întrerupt și reluat (positional memoization) — acest lucru permite lui Compose să repornească doar părțile modificate fără reconstruirea completă a arborelui.
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
)
}
}Funcția UserProfile primește name și avatarUrl ca parametri, construiește un rând cu avatar și nume. Modifier.fillMaxWidth() întinde componentul pe toată lățimea, .padding(16.dp) adaugă margini. MaterialTheme.typography.titleMedium folosește stilul de sistem Material 3. La modificarea parametrilor name sau avatarUrl, Compose repornește UserProfile — recrearea componentului cu noile valori.
State în Compose — orice valoare a cărei modificare cauzează recompoziția (repornirea) funcțiilor @Composable dependente. Metoda de bază este mutableStateOf(), care creează MutableState<T> cu suport pentru sistemul de snapshot-uri Compose. Snapshot — mecanism de urmărire a modificărilor: la scrierea în State, Compose marchează Snapshot-ul curent ca dirty, iar planificatorul de recompoziție repornește doar funcțiile Composable care citesc acest State. Pentru colecții observabile utilizați mutableStateListOf() și mutableStateMapOf(). Compose suportă State din componente Lifecycle-Aware prin collectAsState() pentru Kotlin Flow și observeAsState() pentru 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")
}
}Codul creează un buton «Like» cu starea liked (Boolean) și count (Int), stocate prin mutableStateOf(). La apăsare, liked este inversat, contorul crește/scade — Compose repornește automat LikeButton. by delegate permite utilizarea State ca o variabilă obișnuită: liked = !liked în loc de liked.value = !liked.value. Culoarea butonului se schimbă reactiv între primary (apreciat) și surfaceVariant (neapreciat).
remember — funcția Compose care stochează în cache valoarea între recompoziții. Fără remember, fiecare repornire a funcției Composable creează o stare nouă (mutableStateOf) — acest lucru strică logica aplicației: la rotirea ecranului sau modificarea State-ului părinte, contorul se resetează. remember primește o lambda-calculator și calculează valoarea doar la prima compoziție; la următoarele returnează rezultatul stocat în cache. Pentru resetarea cache-ului utilizați remember(key) — cheia determină când să recalculeze valoarea. remember(key1, key2) recalculează la modificarea oricărei chei. Pentru stări de lungă durată (care supraviețuiesc rotirii ecranului) utilizați rememberSaveable — analogul remember cu salvare în Bundle prin 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 = "Timp scurs: ${seconds}s",
style = MaterialTheme.typography.displayMedium
)
}
}rememberSaveable păstrează seconds la rotirea ecranului (modificare de configurare). LaunchedEffect pornește o corutină care incrementează seconds în fiecare secundă. La recompoziția TimerScreen (în fiecare secundă) seconds nu se resetează datorită lui rememberSaveable. Utilizați remember obișnuit pentru starea care nu ar trebui să supraviețuiască modificărilor de configurare (de exemplu, flag-uri de animație).
Modifier — obiect-container imutabil care implementează pattern-ul Builder pentru setarea aspectului, comportamentului și layout-ului componentelor Composable. Fiecare apel al metodei Modifier (.padding(), .width(), .clickable(), .background()) returnează un nou Modifier cu elementul adăugat. Ordinea modificatorilor contează: .padding(16.dp).clickable { } — marginea se aplică înaintea handler-ului de click, clickable urmărește întreaga zonă ținând cont de margine. .clickable { }.padding(16.dp) — întreaga zonă înainte de margine este clickabilă, marginea deplasează conținutul în interior. Modifier suportă implementări personalizate prin then(otherModifier) și compositionLocal pentru acces la setările părinte.
@Composable
fun CardExample() {
Card(
modifier = Modifier
.fillMaxWidth()
.padding(16.dp)
.clickable { println("Card apăsat") },
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 declarativ pentru Android cu State și Modifier",
style = MaterialTheme.typography.bodyMedium
)
}
}
}CardExample demonstrează lanțul Modifier: fillMaxWidth + padding + clickable. Card — component Material3 cu propriile setări elevation și colors. Column-ul imbricat are un padding intern de 16dp. Compose Material3 ajustează automat culorile la Dynamic Color (Material You) pe Android 12+. Card este unul dintre cele 30+ componente Material3 încorporate în Compose.
State hoisting — pattern-ul de ridicare a stării din funcția Composable în apelantul său, făcând funcția stateless. Componentul stateless primește date și callback-uri prin parametri, neavând propriul State. Aceasta crește reutilizabilitatea și testabilitatea: componentul poate fi apelat cu diferite State și testat în preview. Google recomandă arhitectura: ViewModel + StateFlow (sau MutableStateFlow) + collectAsState() în Compose. ViewModel ridică starea la nivelul ecranului, Compose afișează. Efectele secundare (LaunchedEffect, DisposableEffect) gestionează evenimentele unice.
| Component | Responsabilitate | Tehnologie |
|---|---|---|
| ViewModel | Stocare State, logică de business | StateFlow, MutableStateFlow |
| Screen Composable | Organizarea ecranului, State hoisting | collectAsState(), Scaffold, LazyColumn |
| Stateless Component | UI fără stare, afișare pură | @Composable parametri + lambde |
| Side Effect | Acțiuni unice (snackbar, navigare) | LaunchedEffect, SnackbarHostState |
Întrebări frecvente
Layout-urile XML sunt imperative: LayoutInflater încarcă XML, findViewById găsește View, dezvoltatorul actualizează manual textul/listele. Compose este declarativ: UI se descrie prin funcții Kotlin @Composable, iar framework-ul redesenează automat doar părțile modificate la schimbarea State. Compose reduce volumul codului UI cu 30–50% și nu folosește XML.
Da, Google oferă Navigation Compose — o bibliotecă pentru navigare declarativă între ecrane. NavController gestionează stiva de rute, composable() înregistrează ecranele, navArgument transmite parametri. Alternative: Voyager (comunitate) și Decompose (Badoo). Navigation Compose este standardul oficial cu suport pentru deep links și argumente type-safe.
Modifier — un container imutabil de pattern-uri de styling (padding, size, clickable, background, border, clip) aplicate componentelor Composable. Fiecare apel returnează un nou Modifier cu elementul adăugat. Ordinea contează: .padding().clickable() aplică marginea înainte de click, .clickable().padding() — invers. Modifier este modul principal de personalizare a componentelor Compose.
Jetpack Compose suportă Android API 21+ (Android 5.0 Lollipop) prin Compose Compiler și Compose BOM. Material 3 (Dynamic Colors) este disponibil pe Android 12+; pe versiunile mai vechi se folosește o paletă de rezervă. Pentru proiecte noi, Apple recomandă minSdk 24+ (Android 7.0), ceea ce este acoperit complet de Compose.
Google oferă Compose UI Test — o bibliotecă pentru testare pe JVM (Desktop) și emulator. Funcții principale: composeTestRule.setContent { } pentru randarea componentului, onNodeWithText() pentru căutarea elementelor, performClick()/performTextInput() pentru acțiuni. Testele Espresso sunt compatibile cu Compose prin ComposeTestRule, dar Compose UI Test este abordarea preferată și mai rapidă.
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