Composable Function: ce este, sintaxa funcției și reguli

Autor: IT Sectr Publicat: 2026-06-27 Timp de citire: 8 min

Composable Function — este unitatea fundamentală a interfeței de utilizator în Jetpack Compose, care definește cum ar trebui să arate și să se comporte o parte a ecranului. Fiecare astfel de funcție este marcată cu adnotarea @Composable și se execută într-un context special, permițând Compose să urmărească dependențele și să reconstruiască automat UI la modificarea datelor. Conform Google Android Developers, 2026, construirea corectă a funcțiilor Composable influențează direct performanța aplicației și eficiența recompunerii.

Principalele

  • Composable Function — funcție Kotlin cu adnotarea @Composable care construiește arborele UI
  • Parametrii trebuie să fie imutabili, iar datele variabile — prin state
  • Apelul este posibil doar din contextul altei funcții Composable
  • Ordinea execuției nu este garantată — fiecare funcție trebuie să fie independentă
  • Modifier se recomandă a fi transmis ca parametru pentru personalizare

Ce este Composable Function în Jetpack Compose

Composable Function — este o funcție în limbajul Kotlin marcată cu adnotarea @Composable, care descrie o parte a interfeței de utilizator într-un mod declarativ. În loc să creeze și să configureze obiecte View prin cod Java sau XML, dezvoltatorul scrie pur și simplu cum ar trebui să arate UI pentru fiecare stare a datelor.

Diferența principală dintre funcția Composable și sistemul tradițional View din Android constă în modelul de actualizare. În abordarea clasică, dezvoltatorul apela manual findViewById, modifica textul prin setText, gestiona vizibilitatea prin setVisibility. Composable Function eliberează de această rutină: la modificarea datelor, sistemul determină singur care funcții trebuie repornite și execută doar pe acestea.

Compilatorul Kotlin, procesând adnotarea @Composable, generează cod suplimentar care integrează funcția în mecanismul de compunere. Acest cod include citirea și scrierea în sloturi — celule de memorie speciale care stochează starea și parametrii fiecărei funcții Composable în arborele UI curent. Datorită acestei integrări, Compose știe care funcții depind de care date.

Sintaxa declarării funcției Composable

Sintaxa funcției Composable este cât se poate de concisă: este suficient să adăugați @Composable înainte de cuvântul cheie fun. Funcția poate accepta orice parametri, poate include alte apeluri Composable în corpul său și poate folosi construcții Kotlin — condiții, bucle, expresii when — pentru afișarea condiționată a UI.

kotlin
@Composable
fun ProductItem(
    product: Product,
    modifier: Modifier = Modifier,
    onAddToCart: () -> Unit
) {
    Card(modifier = modifier.padding(8.dp)) {
        Row(modifier = Modifier.fillMaxWidth().padding(12.dp),
            verticalAlignment = Alignment.CenterVertically) {
            Column(modifier = Modifier.weight(1f)) {
                Text(text = product.name, style = MaterialTheme.typography.titleMedium)
                Text(text = "${product.price}", color = MaterialTheme.colorScheme.primary)
            }
            Button(onClick = onAddToCart) {
                Text("Adaugă în coș")
            }
        }
    }
}

În acest exemplu, funcția Composable ProductItem acceptă un obiect Product, un modificator și un callback. Toți cei trei parametri sunt imutabili, ceea ce garantează un comportament previzibil la recompunere. Modificatorul este transmis ca parametru cu o valoare implicită — aceasta este o practică standard care permite părții apelante să personalizeze spațiile și dimensiunile.

Componente și modificatori în funcțiile Composable

În interiorul funcției Composable se folosesc componente încorporate Material Design (Text, Button, Card, TextField) sau primitive fundamentale (Canvas, Layout). Fiecare componentă acceptă parametri pentru configurarea aspectului și comportamentului, precum și unul sau mai mulți modificatori prin parametrul modifier.

Modificatorii (Modifier) — sunt un lanț de funcții care modifică dimensiunea, poziția, gestionarea evenimentelor și aspectul componentei. Ordinea modificatorilor în lanț contează: clickable.semantics funcționează diferit de semantics.clickable, iar padding.background colorează fundalul zonei inclusiv paddingul, ceea ce este critic în proiectare.

În interiorul funcției Composable se pot folosi condiții if și when pentru afișarea condiționată a părților UI, precum și bucle for pentru liste dinamice. Toate aceste construcții funcționează natural, deoarece Kotlin este un limbaj de programare complet. Este important de reținut: dacă condiția sau bucla conține apeluri ale funcțiilor Composable, acestea participă și ele la recompunere.

kotlin
@Composable
fun ProductList(
    products: List<Product>,
    modifier: Modifier = Modifier
) {
    LazyColumn(modifier = modifier) {
        items(products, key = { it.id }) { product ->
            ProductItem(
                product = product,
                onAddToCart = { /* add to cart */ }
            )
        }
    }
}

Exemple de funcții Composable pentru ecrane reale

Să analizăm un exemplu de ecran de căutare a produselor folosind mai multe funcții Composable. Aici sunt prezentate modele tipice: câmp de introducere cu stare, filtrarea listei, gestionarea rezultatului gol și a încărcării.

kotlin
data class Product(
    val id: String,
    val name: String,
    val price: Double,
    val category: String
)

@Composable
fun SearchScreen() {
    var query by remember { mutableStateOf("") }
    val products = remember(query) { getFilteredProducts(query) }

    Column(modifier = Modifier.fillMaxSize().padding(16.dp)) {
        OutlinedTextField(
            value = query,
            onValueChange = { query = it },
            label = { Text("Caută produse") },
            modifier = Modifier.fillMaxWidth()
        )

        Spacer(modifier = Modifier.height(16.dp))

        when (products) {
            is Loading -> CircularProgressIndicator()
            is Empty -> Text("Niciun rezultat găsit")
            is Result -> LazyColumn {
                items(products.items, key = { it.id }) { product ->
                    ProductItem(product = product, onAddToCart = {})
                }
            }
        }
    }
}

Acest exemplu demonstrează simultan mai multe idiomuri: remember pentru salvarea stării interogării de căutare, remember(query) pentru filtrarea cu cheie, when pentru trei stări ale UI și LazyColumn pentru afișarea eficientă a listei. Fiecare dintre aceste idiomuri este rezultatul experienței practice în dezvoltarea aplicațiilor Compose.

Parametri și Slot API

Funcțiile Composable acceptă parametri la fel ca funcțiile obișnuite Kotlin, dar cu o diferență importantă: parametrul poate fi o altă funcție Composable transmisă printr-o lambda cu adnotarea @Composable. Acest mecanism se numește Slot API și este modelul principal pentru crearea containerelor reutilizabile.

Slot API rezolvă problema care în sistemul tradițional View era rezolvată prin ViewGroup și adăugarea programatică a View-urilor copil. În locul metodelor addView, Compose folosește lambda-uri content — ultimul parametru cu tipul @Composable () -> Unit. Partea apelantă transmite în această lambda orice UI, iar containerul însuși determină doar amplasarea acestuia.

Parametrii funcției Composable pot avea valori implicite, ceea ce simplifică utilizarea lor în contexte diferite. Se recomandă să faceți obligatorii doar acei parametri fără de care funcția nu își poate îndeplini sarcina, iar pe ceilalți să îi dotați cu valori implicite rezonabile.

ParametruTipExemplu
ObligatoriuOrice tipname: String
OpționalCu valoare implicitămodifier: Modifier = Modifier
Content@Composable () -> Unitcontent: @Composable () -> Unit
CallbackLambda fără @ComposableonClick: () -> Unit

Idiomuri ale funcțiilor Composable în Kotlin

În comunitatea Compose s-au format câteva idiomuri consacrate care fac funcțiile Composable mai lizibile și mai previzibile. Primul — State Hoisting: starea este ridicată la un nivel superior, iar funcția Composable o primește prin parametri. Acest lucru face funcția pură și reutilizabilă în contexte diferite.

Al doilea idiom — parametri Event-driven. În loc să transmitem ViewModel sau useCase în funcția Composable, se transmit doar callback-uri specifice: onSave, onDelete, onNavigateToDetail. Aceasta reduce cuplarea și simplifică testarea — pentru testul ProductItem nu este nevoie de ViewModel, ci doar de un lambda-stub.

Al treilea idiom — CompositionLocal pentru transmiterea datelor comune prin arborele de compunere. Tema, densitatea ecranului, ruta curentă — toate acestea se transmit prin CompositionLocal, evitând lanțuri de parametri prin zeci de funcții Composable. Cu toate acestea, nu trebuie abuzat de CompositionLocal: parametrii explicitați sunt întotdeauna preferabili dependențelor implicite.

kotlin
// State Hoisting: stare ridicată la funcția părinte
@Composable
fun CounterDisplay(
    count: Int,
    onIncrement: () -> Unit
) {
    Column(horizontalAlignment = Alignment.CenterHorizontally) {
        Text(text = "Contor: $count", style = MaterialTheme.typography.headlineLarge)
        Button(onClick = onIncrement) {
            Text("+1")
        }
    }
}

// Utilizare cu State Hoisting
@Composable
fun CounterScreen() {
    var count by remember { mutableStateOf(0) }
    CounterDisplay(
        count = count,
        onIncrement = { count++ }
    )
}

Întrebări frecvente

Se poate folosi return într-o funcție Composable?

Da, return este permis, dar cu prudență. Compose optimizează recompunerea la nivelul funcțiilor individuale, iar o returnare timpurie poate perturba această optimizare. Este mai bine să folosiți operatori condiționali if sau when în interiorul corpului funcției.

Cu ce diferă Unit-return de void în Java?

În Kotlin, Unit este un obiect singleton, nu un tip gol. Funcțiile Composable returnează Unit, ceea ce înseamnă tehnic că returnează însuși obiectul Unit. Cu toate acestea, în practică nu contează — valoarea returnată este ignorată de sistemul de compunere.

Se poate transmite mutableListOf într-o funcție Composable?

Transmiterea colecțiilor mutabile este posibilă, dar este o practică proastă. Dacă colecția se modifică, Compose nu va afla despre aceasta, deoarece referința la obiect rămâne aceeași. Folosiți liste imutabile sau mutableStateListOf pentru modificări urmăribile.

Cum se depanează o funcție Composable?

Pentru depanare, folosiți Android Studio cu Layout Inspector, care arată arborele curent al funcțiilor Composable, valorile parametrilor și motivele recompunerii. Funcționează și debugger-ul obișnuit Kotlin — punctele de întrerupere din interiorul funcțiilor Composable se declanșează corect la fiecare recompunere.

Este obligatoriu să se specifice return type la funcția Composable?

Funcția Composable returnează întotdeauna Unit, prin urmare return type nu se specifică. Încercarea de a returna un alt tip va cauza o eroare de compilare, deoarece adnotarea @Composable este incompatibilă cu tipurile de returnare diferite de Unit.

Rezumat

  • Composable Function — bloc constructiv declarativ UI, marcat cu @Composable
  • Parametrii trebuie să fie imutabili pentru o recompunere previzibilă
  • Modificatorii și Slot API asigură flexibilitate și reutilizare fără moștenire
  • State Hoisting — ridicarea stării la nivel superior pentru puritate și testabilitate
  • Event-driven callback-uri reduc cuplarea cu ViewModel și logica de business
  • CompositionLocal este folosit pentru date comune, dar parametrii explicitați sunt preferați
  • Idiomurile Compose fac codul previzibil, testabil și performant

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.

Discutați proiectul

Citiți și