Composable Function — Jetpack Compose-da istifadəçi interfeysinin əsas vahididir və ekranın bir hissəsinin necə görünməli və davranmalı olduğunu müəyyən edir. Hər bir belə funksiya @Composable annotasiyası ilə işarələnir və Compose-ə asılılıqları izləməyə və məlumat dəyişdikdə UI-ni avtomatik yenidən qurmağa imkan verən xüsusi kontekstdə icra olunur. Google Android Developers, 2026-ya görə, Composable-funksiyaların düzgün qurulması tətbiqin performansına və rekompozisiyanın səmərəliliyinə birbaşa təsir göstərir.
Əsas məqamlar
Composable Function — Kotlin dilində @Composable annotasiyası ilə işarələnmiş, istifadəçi interfeysinin bir hissəsini deklarativ şəkildə təsvir edən funksiyadır. Java kodu və ya XML işarələməsi ilə View obyektləri yaratmaq və konfiqurasiya etmək əvəzinə, tərtibatçı sadəcə UI-nin hər məlumat vəziyyətində necə görünməli olduğunu yazır.
Composable-funksiya ilə ənənəvi Android View sistemi arasındakı əsas fərq yeniləmə modelindədir. Klassik yanaşmada tərtibatçı əl ilə findViewById çağırır, setText ilə mətni dəyişir, setVisibility ilə görünürlüyü idarə edirdi. Composable Function bu rutindən azad edir: məlumat dəyişdikdə sistem özü hansı funksiyaların yenidən işə salınmalı olduğunu müəyyən edir və yalnız onları icra edir.
Kotlin kompilyatoru @Composable annotasiyasını emal edərək funksiyanı kompozisiya mexanizminə inteqrasiya edən əlavə kod generasiya edir. Bu kod slotlara — cari UI ağacında hər Composable-funksiyanın vəziyyətini və parametrlərini saxlayan xüsusi yaddaş hüceyrələrinə oxuma və yazma əməliyyatlarını əhatə edir. Bu inteqrasiya sayəsində Compose hansı funksiyaların hansı məlumatlardan asılı olduğunu bilir.
Composable-funksiyanın sintaksisi maksimum yığcamdır: fun açar sözündən əvvəl @Composable əlavə etmək kifayətdir. Funksiya istənilən parametrləri qəbul edə, öz gövdəsində digər Composable çağırışlarını daxil edə və UI-nin şərti göstərilməsi üçün Kotlin konstruksiyalarından — şərtlərdən, dövrlərdən, when ifadələrindən — istifadə edə bilər.
@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("Səbətə əlavə et")
}
}
}
}
Bu nümunədə ProductItem Composable-funksiyası Product obyektini, modifikatoru və callback-i qəbul edir. Hər üç parametr dəyişməzdir ki, bu da rekompozisiyada proqnozlaşdırıla bilən davranışı təmin edir. Modifikator standart dəyərlə parametr kimi ötürülmüşdür — bu, çağıran tərəfə boşluqları və ölçüləri fərdiləşdirməyə imkan verən standar təcrübədir.
Composable-funksiyanın daxilində Material Design-ın daxili komponentlərindən (Text, Button, Card, TextField) və ya fundamental primitivlərdən (Canvas, Layout) istifadə olunur. Hər komponent görünüş və davranışı konfiqurasiya etmək üçün parametrləri, həmçinin modifier parametri vasitəsilə bir və ya daha çox modifikatoru qəbul edir.
Modifikatorlar (Modifier) — komponentin ölçüsünü, mövqeyini, hadisə idarəetməsini və görünüşünü dəyişən funksiyalar zənciridir. Modifikatorların sırası zəncirdə əhəmiyyətlidir: clickable.semantics semantics.clickable-dan fərqli işləyir, padding.background isə padding daxil olmaqla fon sahəsini rəngləyir ki, bu da dizayn zamanı kritik əhəmiyyət kəsb edir.
Composable-funksiyanın daxilində UI hissələrinin şərti göstərilməsi üçün if və when şərtlərindən, dinamik siyahılar üçün for dövrlərindən istifadə etmək olar. Bütün bu konstruksiyalar təbii şəkildə işləyir, çünki Kotlin tam hüquqlu proqramlaşdırma dilidir. Ancaq yadda saxlamaq vacibdir: əgər şərt və ya dövr Composable-funksiya çağırışları ehtiva edirsə, onlar da rekompozisiyada iştirak edir.
@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 */ }
)
}
}
}
Bir neçə Composable-funksiyadan istifadə edərək məhsul axtarış ekranı nümunəsinə baxaq. Burada tipik nümunələr göstərilib: vəziyyətli daxiletmə sahəsi, siyahının filtrasiyası, boş nəticə və yükləmənin idarə edilməsi.
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("Məhsulları axtar") },
modifier = Modifier.fillMaxWidth()
)
Spacer(modifier = Modifier.height(16.dp))
when (products) {
is Loading -> CircularProgressIndicator()
is Empty -> Text("Nəticə tapılmadı")
is Result -> LazyColumn {
items(products.items, key = { it.id }) { product ->
ProductItem(product = product, onAddToCart = {})
}
}
}
}
}
Bu nümunə bir neçə idiomu eyni anda nümayiş etdirir: axtarış sorğusunun vəziyyətini saxlamaq üçün remember, açar ilə filtrasiya üçün remember(query), UI-nin üç vəziyyəti üçün when və siyahının effektiv göstərilməsi üçün LazyColumn. Bu idiomların hər biri Compose tətbiqlərinin hazırlanmasında praktiki təcrübənin nəticəsidir.
Composable-funksiyalar parametrləri adi Kotlin funksiyaları kimi qəbul edir, lakin bir mühüm fərqlə: parametr @Composable annotasiyası ilə lambda vasitəsilə ötürülən başqa bir Composable-funksiya ola bilər. Bu mexanizm Slot API adlanır və təkrar istifadə oluna bilən konteynerlər yaratmaq üçün əsas nümunədir.
Slot API ənənəvi View sistemində ViewGroup və uşaq View-lərin proqram vasitəsilə əlavə edilməsi ilə həll olunan problemi həll edir. addView metodları əvəzinə Compose content-lambdalarından — @Composable () -> Unit tipində son parametrdən istifadə edir. Çağıran tərəf bu lambdaya istənilən UI-ni ötürür, konteyner isə yalnız onun yerləşməsini müəyyən edir.
Composable-funksiyanın parametrləri standart dəyərlərə malik ola bilər ki, bu da onların müxtəlif kontekstlərdə istifadəsini asanlaşdırır. Tövsiyə olunur yalnız funksiyanın öz vəzifəsini yerinə yetirə bilmədiyi parametrləri məcburi etmək, qalanlarını isə məqbul standart dəyərlərlə təmin etmək.
| Parametr | Tip | Nümunə |
|---|---|---|
| Məcburi | İstənilən tip | name: String |
| İstəyə bağlı | Standart dəyərlə | modifier: Modifier = Modifier |
| Content | @Composable () -> Unit | content: @Composable () -> Unit |
| Callback | @Composable olmayan lambda | onClick: () -> Unit |
Compose icmasında Composable-funksiyaları daha oxunaqlı və proqnozlaşdırıla bilən edən bir neçə qurulmuş idiom formalaşıb. Birincisi — State Hoisting: vəziyyət yuxarı səviyyəyə qaldırılır, Composable-funksiya isə onu parametrlər vasitəsilə alır. Bu, funksiyanı təmiz və müxtəlif kontekstlərdə təkrar istifadə oluna bilən edir.
İkinci idiom — Event-driven parametrlər. Composable-funksiyaya ViewModel və ya useCase ötürmək əvəzinə, yalnız konkret callbacklər ötürülür: onSave, onDelete, onNavigateToDetail. Bu, asılılıqları azaldır və testləri asanlaşdırır — ProductItem-in testi üçün ViewModel deyil, yalnız lambda-stub lazımdır.
Üçüncü idiom — kompozisiya ağacı vasitəsilə ümumi məlumatları ötürmək üçün CompositionLocal. Tema, ekran sıxlığı, cari marşrut — bunların hamısı onlarla Composable-funksiya vasitəsilə parametr zəncirlərindən qaçaraq CompositionLocal vasitəsilə ötürülür. Lakin CompositionLocal-dan həddindən artıq istifadə etmək olmaz: aşkar parametrlər həmişə qeyri-aşkar asılılıqlardan üstündür.
// State Hoisting: vəziyyət ana funksiyaya qaldırıldı
@Composable
fun CounterDisplay(
count: Int,
onIncrement: () -> Unit
) {
Column(horizontalAlignment = Alignment.CenterHorizontally) {
Text(text = "Sayğac: $count", style = MaterialTheme.typography.headlineLarge)
Button(onClick = onIncrement) {
Text("+1")
}
}
}
// State Hoisting ilə istifadə
@Composable
fun CounterScreen() {
var count by remember { mutableStateOf(0) }
CounterDisplay(
count = count,
onIncrement = { count++ }
)
}
Tez-tez verilən suallar
Bəli, return icazəlidir, lakin ehtiyatla. Compose rekompozisiyanı ayrı-ayrı funksiyalar səviyyəsində optimallaşdırır və erkən return bu optimallaşdırmanı poza bilər. Funksiya gövdəsində if və ya when şərt operatorlarından istifadə etmək daha yaxşıdır.
Kotlin-də Unit boş tip deyil, singleton obyektdir. Composable-funksiyalar Unit qaytarır, bu texniki olaraq onların Unit obyektinin özünü qaytarması deməkdir. Lakin praktikada bunun əhəmiyyəti yoxdur — qaytarılan dəyər kompozisiya sistemi tərəfindən nəzərə alınmır.
Dəyişən kolleksiyaları ötürmək olar, lakin bu pis təcrübədir. Kolleksiya dəyişərsə, Compose bu barədə bilməyəcək, çünki obyektə istinad eyni qalır. İzlənilən dəyişikliklər üçün immutable siyahılar və ya mutableStateListOf istifadə edin.
Debug üçün cari Composable-funksiyalar ağacını, parametr dəyərlərini və rekompozisiya səbəblərini göstərən Layout Inspector ilə Android Studio istifadə edin. Adi Kotlin debugeri də işləyir — Composable-funksiyalar daxilindəki breakpoint-lər hər rekompozisiyada düzgün işə düşür.
Composable-funksiya həmişə Unit qaytarır, buna görə return type göstərilmir. Başqa tip qaytarmaq cəhdi kompilyasiya xətasına səbəb olacaq, çünki @Composable annotasiyası Unit olmayan qaytarılan tiplərlə uyğunsuzdur.
Nəticə
Açar təslim mobil tətbiq hazırlayacağıq
IT Sectr 2017-ci ildən startaplar və bizneslər üçün iOS və Android tətbiqləri yaradır. Sizə məsləhət verəcəyik və ən yaxşı həlli təklif edəcəyik.
Həm də oxuyun