Composable Function — a Jetpack Compose felhasználói felületének alapvető egysége, amely meghatározza, hogy a képernyő egy részének hogyan kell kinéznie és viselkednie. Minden ilyen függvény @Composable annotációval van jelölve, és egy speciális kontextusban hajtódik végre, lehetővé téve a Compose számára a függőségek nyomon követését és az UI automatikus újraépítését az adatok változásakor. A Google Android Developers, 2026 szerint a Composable függvények helyes felépítése közvetlenül befolyásolja az alkalmazás teljesítményét és a recomposition hatékonyságát.
Főbb pontok
Composable Function — egy Kotlin nyelvű függvény, amely @Composable annotációval van jelölve, és a felhasználói felület egy részét deklaratív módon írja le. Ahelyett, hogy View objektumokat hozna létre és konfigurálna Java kódon vagy XML jelölésen keresztül, a fejlesztő egyszerűen leírja, hogy az UI hogyan nézzen ki minden adatállapotban.
A fő különbség a Composable függvény és a hagyományos Android View rendszer között a frissítési modellben rejlik. A klasszikus megközelítésben a fejlesztő manuálisan hívta meg a findViewById-t, módosította a szöveget a setText-en keresztül, kezelte a láthatóságot a setVisibility-n keresztül. Composable Function megszabadít ettől a rutintól: az adatok változásakor a rendszer maga határozza meg, mely függvényeket kell újraindítani, és csak azokat hajtja végre.
A Kotlin fordító a @Composable annotáció feldolgozásakor további kódot generál, amely integrálja a függvényt a kompozíciós mechanizmusba. Ez a kód magában foglalja a slotokba — speciális memóriacellákba, amelyek az egyes Composable függvények állapotát és paramétereit tárolják az aktuális UI-fában — történő olvasást és írást. Ennek az integrációnak köszönhetően a Compose tudja, mely függvények mely adatoktól függenek.
A Composable függvény szintaxisa rendkívül tömör: elég a fun kulcsszó elé tenni a @Composable-t. A függvény bármilyen paramétert elfogadhat, tartalmazhat más Composable hívásokat a törzsében, és használhat Kotlin konstrukciókat — feltételeket, ciklusokat, when kifejezéseket — az UI feltételes megjelenítéséhez.
@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("Kosárba tesz")
}
}
}
}
Ebben a példában a ProductItem Composable függvény egy Product objektumot, egy módosítót és egy callback-et fogad el. Mindhárom paraméter megváltoztathatatlan, ami kiszámítható viselkedést garantál a recomposition során. A módosító alapértelmezett értékkel rendelkező paraméterként lett átadva — ez egy szabványos gyakorlat, amely lehetővé teszi a hívó fél számára a margók és méretek testreszabását.
A Composable függvényen belül beépített Material Design komponensek (Text, Button, Card, TextField) vagy alapvető primitívek (Canvas, Layout) használatosak. Minden komponens paramétereket fogad el a megjelenés és viselkedés konfigurálásához, valamint egy vagy több módosítót a modifier paraméteren keresztül.
A módosítók (Modifier) — függvények lánca, amelyek megváltoztatják a komponens méretét, pozícióját, eseménykezelését és megjelenését. A módosítók sorrendje a láncban fontos: a clickable.semantics másképp működik, mint a semantics.clickable, és a padding.background a paddingot is beleértve színezi a háttérterületet, ami kritikus a tervezés során.
A Composable függvényen belül használhatók if és when feltételek az UI részeinek feltételes megjelenítéséhez, valamint for ciklusok dinamikus listákhoz. Mindezek a konstrukciók természetesen működnek, mivel a Kotlin egy teljes értékű programozási nyelv. Fontos azonban megjegyezni: ha a feltétel vagy ciklus Composable függvényhívásokat tartalmaz, azok is részt vesznek a recomposition-ben.
@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 */ }
)
}
}
}
Vizsgáljunk meg egy termékkereső képernyő példát több Composable függvény használatával. Itt tipikus minták láthatók: beviteli mező állapottal, lista szűrése, üres eredmény és betöltés kezelése.
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("Termékek keresése") },
modifier = Modifier.fillMaxWidth()
)
Spacer(modifier = Modifier.height(16.dp))
when (products) {
is Loading -> CircularProgressIndicator()
is Empty -> Text("Nincs találat")
is Result -> LazyColumn {
items(products.items, key = { it.id }) { product ->
ProductItem(product = product, onAddToCart = {})
}
}
}
}
}
Ez a példa egyszerre több idiómát is bemutat: remember a keresési lekérdezés állapotának mentéséhez, remember(query) a kulccsal történő szűréshez, when az UI három állapotához és LazyColumn a lista hatékony megjelenítéséhez. Ezen idiómák mindegyike a Compose alkalmazások fejlesztésében szerzett gyakorlati tapasztalat eredménye.
A Composable függvények ugyanúgy fogadnak el paramétereket, mint a szokásos Kotlin függvények, de egy fontos különbséggel: a paraméter lehet egy másik Composable függvény, amely @Composable annotációval ellátott lambdán keresztül lett átadva. Ezt a mechanizmust Slot API-nak hívják, és ez a fő minta újrafelhasználható konténerek létrehozásához.
A Slot API megoldja azt a problémát, amelyet a hagyományos View rendszerben a ViewGroup és a gyermek View-k programozott hozzáadása oldott meg. Az addView metódusok helyett a Compose content lambdákat használ — az utolsó paramétert @Composable () -> Unit típussal. A hívó fél bármilyen UI-t átad ennek a lambdának, a konténer pedig csak annak elhelyezését határozza meg.
A Composable függvény paraméterei rendelkezhetnek alapértelmezett értékekkel, ami leegyszerűsíti használatukat különböző kontextusokban. Ajánlott csak azokat a paramétereket kötelezővé tenni, amelyek nélkül a függvény nem tudja ellátni a feladatát, a többit pedig ésszerű alapértelmezett értékekkel ellátni.
| Paraméter | Típus | Példa |
|---|---|---|
| Kötelező | Bármilyen típus | name: String |
| Opcionális | Alapértelmezett értékkel | modifier: Modifier = Modifier |
| Content | @Composable () -> Unit | content: @Composable () -> Unit |
| Callback | Lambda @Composable nélkül | onClick: () -> Unit |
A Compose közösségben számos bevett idioma alakult ki, amelyek a Composable függvényeket olvashatóbbá és kiszámíthatóbbá teszik. Az első — State Hoisting: az állapot egy magasabb szintre kerül, és a Composable függvény paramétereken keresztül kapja meg. Ez tisztává és újrafelhasználhatóvá teszi a függvényt különböző kontextusokban.
A második idioma — az Event-driven paraméterek. Ahelyett, hogy ViewModel-t vagy useCase-t adnánk át a Composable függvénynek, csak konkrét callback-ek kerülnek átadásra: onSave, onDelete, onNavigateToDetail. Ez csökkenti a kapcsolódást és leegyszerűsíti a tesztelést — a ProductItem tesztjéhez nem kell ViewModel, csak egy lambda-stub.
A harmadik idioma — CompositionLocal a közös adatok kompozíciós fán keresztül történő átadásához. Téma, képernyősűrűség, aktuális útvonal — mindez a CompositionLocal-on keresztül kerül átadásra, elkerülve a paraméterláncokat tucatnyi Composable függvényen keresztül. A CompositionLocal-t azonban nem szabad túlhasználni: az explicit paraméterek mindig előnyösebbek az implicit függőségekkel szemben.
// State Hoisting: állapot a szülő függvénybe emelve
@Composable
fun CounterDisplay(
count: Int,
onIncrement: () -> Unit
) {
Column(horizontalAlignment = Alignment.CenterHorizontally) {
Text(text = "Számláló: $count", style = MaterialTheme.typography.headlineLarge)
Button(onClick = onIncrement) {
Text("+1")
}
}
}
// Használat State Hoisting-gal
@Composable
fun CounterScreen() {
var count by remember { mutableStateOf(0) }
CounterDisplay(
count = count,
onIncrement = { count++ }
)
}
Gyakran Ismételt Kérdések
Igen, a return megengedett, de óvatosan. A Compose a recomposition-t az egyes függvények szintjén optimalizálja, és a korai return megzavarhatja ezt az optimalizálást. Jobb feltételes operátorokat, if vagy when használni a függvény törzsén belül.
Kotlin-ban a Unit egy singleton objektum, nem egy üres típus. A Composable függvények Unit-ot adnak vissza, ami technikailag azt jelenti, hogy magát a Unit objektumot adják vissza. A gyakorlatban azonban ennek nincs jelentősége — a visszatérési értéket a kompozíciós rendszer figyelmen kívül hagyja.
Módosítható kollekciók átadása lehetséges, de rossz gyakorlat. Ha a kollekció megváltozik, a Compose nem fog tudni róla, mert az objektumra való hivatkozás ugyanaz marad. Használjon immutable listákat vagy mutableStateListOf-ot a követhető változásokhoz.
Debug-hoz használja az Android Studio-t a Layout Inspector-ral, amely megjeleníti a Composable függvények aktuális fáját, a paraméterek értékeit és a recomposition okait. A szokásos Kotlin debugger is működik — a Composable függvényeken belüli töréspontok minden recomposition-kor helyesen aktiválódnak.
A Composable függvény mindig Unit-ot ad vissza, ezért a return type nincs megadva. Egy másik típus visszaadására tett kísérlet fordítási hibát eredményez, mivel a @Composable annotáció nem kompatibilis a nem-Unit visszatérési típusokkal.
Összefoglalás
Kulcsrakész mobilalkalmazást fejlesztünk
Az IT Sectr 2017 óta készít iOS és Android alkalmazásokat induló vállalkozásoknak és vállalkozásoknak. Tanácsot adunk, és a legjobb megoldást javasoljuk.
Olvassa el is