Jetpack Compose: τι είναι, βασικές έννοιες και συναρτήσεις composable

Συγγραφέας: IT Sectr Δημοσιεύτηκε: 2026-05-01 Χρόνος ανάγνωσης: 9 λεπ

Το Jetpack Compose είναι ένα σύγχρονο declarative toolkit για τη δημιουργία διεπαφών Android σε Kotlin. Ο προγραμματιστής περιγράφει το UI μέσω συναρτήσεων composable και το toolkit ανασχεδιάζει αυτόματα μόνο τα τμήματα που άλλαξαν. Σύμφωνα με το Android Developers (2026), το Jetpack Compose λειτουργεί σε Android 5.0 (API 21) και νεότερα, υποστηρίζει Material Design 3 και φτάνει τα 120 FPS σε συσκευές μεσαίας κατηγορίας χάρη στο δικό του σύστημα Recomposition — έναν έξυπνο αλγόριθμο diff που ενημερώνει μόνο τα widget που άλλαξαν.

Κύρια σημεία

  • Jetpack Compose — ένα declarative UI framework για Android, όπου η διεπαφή χτίζεται μέσω σχολιασμένων συναρτήσεων @Composable σε Kotlin.
  • Recomposition — μηχανισμός αυτόματης ενημέρωσης μόνο των στοιχείων των οποίων τα δεδομένα άλλαξαν, εξασφαλίζοντας 120 FPS.
  • State διαχειρίζεται μέσω mutableStateOf, collectAsState και StateFlow — όταν αλλάξει η τιμή, η σύνθεση επανεκκινείται για τις εξαρτημένες προβολές.
  • Modifier — αλυσίδα συναρτήσεων για τη διαμόρφωση αποστάσεων, μεγεθών, φόντου, κλικ και κινήσεων χωρίς κληρονομικότητα κλάσεων.
  • Side Effects — LaunchedEffect, DisposableEffect και rememberCoroutineScope — διαχειρίζονται παρενέργειες: χρονοδιακόπτες, αιτήματα δικτύου, συνδρομές.

Τι είναι το Jetpack Compose;

Jetpack Compose — είναι ένα declarative framework από την Google για τη δημιουργία διεπαφών χρήστη Android, που ανακοινώθηκε το 2019 και έφτασε σε σταθερή έκδοση το 2021. Σε αντίθεση με το παλιό View System (XML + Activity/Fragment), το Compose χρησιμοποιεί σχολιασμένες συναρτήσεις Kotlin — @Composable. Η διεπαφή περιγράφεται εξ ολοκλήρου σε Kotlin: δεν υπάρχει διαχωρισμός μεταξύ XML και κώδικα. Αυτό εξάλειψε μια κατηγορία σφαλμάτων που σχετίζονται με ασυμφωνία id σε XML και Kotlin (το type-safe synthetic δεν βοηθούσε κατά την αναδιάρθρωση κώδικα).

Το Compose είναι χτισμένο στο δικό του σύστημα απόδοσης — Canvas, που δεν είναι δεμένο στην ιεραρχία View. Κάθε Composable σχεδιάζει απευθείας στο Canvas, παρακάμπτοντας το onMeasure/onDraw του View System. Αυτό δίνει αύξηση απόδοσης σε σύνθετες οθόνες: στις δοκιμές της Google (2023) μια οθόνη Compose με 200 στοιχεία αποδόθηκε 40% ταχύτερα από την αντίστοιχη σε RecyclerView + ViewHolder.

Ελάχιστες απαιτήσεις και συμβατότητα

Για τη λειτουργία του Compose απαιτείται minSdk 21 (Android 5.0) και Kotlin 1.9+. Το Compose BOM (Bill of Materials) συγχρονίζει τις εκδόσεις όλων των βιβλιοθηκών Compose. Το framework είναι συμβατό με υπάρχοντα κώδικα σε View System: το Compose ενσωματώνεται μέσω ComposeView σε XML και το παλιό View μέσω AndroidView στην ιεραρχία Compose. Σύμφωνα με το Google Play Console (2025), το Android 5.0+ καλύπτει το 97% των ενεργών συσκευών, επομένως η συμβατότητα δεν αποτελεί περιορισμό για τα περισσότερα έργα.

Συναρτήσεις Composable και σύνθεση

@Composable — είναι ένας σχολιασμός που μετατρέπει μια συνηθισμένη συνάρτηση Kotlin σε δομικό στοιχείο UI. Η συνάρτηση Composable περιγράφει πώς πρέπει να μοιάζει ένα τμήμα διεπαφής — κείμενο, κουμπί, λίστα. Αντί να επιστρέφει τιμή, η συνάρτηση εκπέμπει στοιχεία UI στη σύνθεση. Αυτό μοιάζει με γεννήτρια: κάθε συνάρτηση προσθέτει στοιχεία στην οθόνη όταν καλείται.

kotlin
@Composable
fun ProfileCard(name: String, avatarUrl: String) {
    Card(
        modifier = Modifier.fillMaxWidth().padding(16.dp),
        colors = CardDefaults.cardColors(
            containerColor = MaterialTheme.colorScheme.surface
        )
    ) {
        Row(verticalAlignment = Alignment.CenterVertically) {
            AsyncImage(
                model = avatarUrl,
                contentDescription = "Άβαταρ",
                modifier = Modifier.size(48.dp).clip(CircleShape)
            )
            Spacer(Modifier.width(12.dp))
            Text(
                text = name,
                style = MaterialTheme.typography.titleMedium
            )
        }
    }
}

Η συνάρτηση ProfileCard δέχεται παραμέτρους (name, avatarUrl) και εκπέμπει Card → Row → AsyncImage + Text. Σύνθεση — είναι ένα δέντρο εκπεμπόμενων στοιχείων σε ένα πέρασμα. Εάν οι παράμετροι δεν άλλαξαν, το Compose παραλείπει την κλήση της συνάρτησης (recomposition skip). Εάν άλλαξε μόνο το name, θα κληθεί μόνο το Text, τα υπόλοιπα στοιχεία δεν θα ανασχεδιαστούν. Αυτή η intelligent recomposition — είναι το βασικό πλεονέκτημα απόδοσης του Compose έναντι της χειροκίνητης βελτιστοποίησης του View System.

Slots και Content Lambda

Οι συναρτήσεις Composable χρησιμοποιούν ενεργά slots — trailing lambda, content: @Composable (() -> Unit). Αυτό επιτρέπει τη δημιουργία δοχείων: Card, Column, Row δέχονται content lambda και το περιεχόμενο ενσωματώνεται στη θέση του slot. Το Slot API αντικατέστησε χαρακτηριστικά XML όπως το android:layout_gravity — τώρα η θέση των θυγατρικών στοιχείων καθορίζεται από κώδικα Kotlin μέσα στο μπλοκ content.

Διαχείριση κατάστασης στο Compose

Κατάσταση στο Compose — είναι οποιαδήποτε τιμή μπορεί να αλλάξει με την πάροδο του χρόνου. Όταν αλλάζει η κατάσταση, το Compose προγραμματίζει recomposition για όλα τα στοιχεία που διαβάζουν αυτήν την κατάσταση. Ο μηχανισμός θυμίζει React hooks: η mutableStateOf επιστρέφει MutableState, η ανάγνωση του .value εγγράφει αυτόματα την τρέχουσα σύνθεση στις αλλαγές.

kotlin
@Composable
fun CounterExample() {
    var count by remember { mutableStateOf(0) }

    Column(modifier = Modifier.padding(16.dp)) {
        Text("Πατήθηκε: $count")
        Button(onClick = { count++ }) {
            Text("Αύξηση")
        }
    }
}

@Composable
fun UserScreen(viewModel: UserViewModel) {
    val userName by viewModel.userName.collectAsState()
    Text("Χρήστης: $userName")
}

Η remember διατηρεί την τιμή μεταξύ των ανασυνθέσεων — διαφορετικά η mutableStateOf θα δημιουργούνταν εκ νέου σε κάθε ενημέρωση UI. Η collectAsState() μετατρέπει το StateFlow από ViewModel σε κατάσταση συμβατή με Compose. Σύσταση — για κατάσταση οθόνης χρησιμοποιήστε ViewModel με StateFlow, για τοπική κατάσταση (π.χ. ανοιγμένη κάρτα) — mutableStateOf. Αυτός ο διαχωρισμός αντιστοιχεί στην αρχή των “έξυπνων/χαζών” στοιχείων.

State Hoisting

State Hoisting — μοτίβο μεταφοράς κατάστασης από θυγατρικό στοιχείο σε γονικό. Ο γονέας μεταβιβάζει τιμή και callback μέσω παραμέτρων, το θυγατρικό καλεί το callback όταν αλλάξει. Ο γονέας αποθηκεύει mutableStateOf, το θυγατρικό — μόνο παραμέτρους. Αυτό κάνει το στοιχείο επαναχρησιμοποιήσιμο και δοκιμάσιμο: το ίδιο TextField μπορεί να χρησιμοποιηθεί με οποιαδήποτε πηγή δεδομένων.

Modifier — διαμόρφωση εμφάνισης

Modifier — είναι ένα αντικείμενο που περιγράφει μετασχηματισμούς Composable: μέγεθος, αποστάσεις, φόντο, επεξεργασία κλικ, κίνηση, κύλιση. Οι τροποποιητές εφαρμόζονται μέσω αλυσίδας κλήσεων: Modifier.fillMaxWidth().padding(16.dp).background(Color.Blue).clickable { }. Κάθε κλήση επιστρέφει έναν νέο Modifier με την προστιθέμενη ιδιότητα — χωρίς μετάλλαξη του αρχικού αντικειμένου.

Η σειρά των τροποποιητών είναι σημαντική. Το Modifier.padding(16.dp).background(Color.Blue) χρωματίζει την περιοχή με απόσταση. Το Modifier.background(Color.Blue).padding(16.dp) χρωματίζει το εσωτερικό ορθογώνιο, ενώ η απόσταση παραμένει διαφανής. Μηχανική μοιάζει με το μοντέλο CSS box: padding → background λειτουργεί σαν margin + background; background → padding — σαν background + padding εσωτερικά. Ο προγραμματιστής χρειάζεται να θυμάται: padding πρώτα = εξωτερική απόσταση, padding μετά = εσωτερική.

Προσαρμοσμένοι τροποποιητές

Εάν οι ενσωματωμένοι τροποποιητές δεν επαρκούν, δημιουργείται προσαρμοσμένος μέσω Modifier.composed { ... } ή Modifier.then(). Μέσα στον προσαρμοσμένο τροποποιητή μπορούν να χρησιμοποιηθούν μετρήσεις διάταξης (Modifier.layout { measurable, constraints -> ... }), σχεδίαση (Modifier.drawWithContent { ... }), χειρονομίες (Modifier.pointerInput { ... }). Παράδειγμα: τροποποιητής για παλλόμενη κίνηση στο πάτημα — μετράει το μέγεθος, στο κλικ ξεκινά κίνηση κλίμακας μέσω animateFloatAsState.

Για κινήσεις το Compose παρέχει animate*AsState (animateFloatAsState, animateColorAsState, animateDpAsState) — οι τιμές κινούνται μεταξύ παλιάς και νέας κατάστασης όταν αλλάζουν. Εάν χρειάζεται κίνηση εμφάνισης/εξαφάνισης — AnimatedVisibility και AnimatedContent με ενσωματωμένες μεταβάσεις (fade, slide, expand). Όλες οι κινήσεις λειτουργούν στο επίπεδο γραφικών, χωρίς να προκαλούν περιττή σύνθεση.

Side Effects: LaunchedEffect, DisposableEffect, remember

Οι συναρτήσεις Composable δεν πρέπει να εκτελούν άμεσα παρενέργειες (αιτήματα δικτύου, χρονοδιακόπτες, συνδρομές) — καλούνται σε κάθε ανασύνθεση, που θα οδηγούσε σε διπλασιασμό αιτημάτων. Για παρενέργειες το Compose παρέχει την οικογένεια συναρτήσεων Effect: LaunchedEffect ξεκινά ένα coroutine κατά την είσοδο στη σύνθεση και το ακυρώνει κατά την έξοδο, DisposableEffect — για πόρους που απαιτούν ρητό καθαρισμό (αισθητήρες, BroadcastReceiver).

kotlin
@Composable
fun SensorReader() {
    val context = LocalContext.current
    var sensorValue by remember { mutableStateOf(0f) }

    DisposableEffect(Unit) {
        val sensor = registerSensorListener(context) { value ->
            sensorValue = value
        }
        onDispose {
            unregisterSensorListener(sensor)
        }
    }

    Text("Τιμή: $sensorValue")
}

@Composable
fun UserGreeting(userId: String) {
    LaunchedEffect(userId) {
        val profile = api.fetchProfile(userId)
        // ενημέρωση κατάστασης
    }
}

LaunchedEffect(userId) επανεκκινείται εάν το userId άλλαξε — το προηγούμενο coroutine ακυρώνεται, ένα νέο ξεκινά με το νέο userId. Αυτό εξαλείφει τη χειροκίνητη διαχείριση ακύρωσης αιτημάτων. DisposableEffect(Unit) — αποτέλεσμα με σταθερό κλειδί Unit, ενεργοποιείται κατά την είσοδο στη σύνθεση και καλεί onDispose κατά την έξοδο. Το SensorReader καταχωρεί έναν ακροατή και διαγράφει τη συνδρομή κατά την έξοδο από την οθόνη — χωρίς κίνδυνο διαρροής μνήμης.

rememberCoroutineScope

Εάν ένα coroutine πρέπει να ξεκινήσει όχι κατά την είσοδο στη σύνθεση, αλλά μετά από ένα συμβάν (πάτημα κουμπιού), χρησιμοποιείται rememberCoroutineScope(). Επιστρέφει ένα CoroutineScope δεμένο στον κύκλο ζωής του Composable, χωρίς να απαιτεί DisposableEffect. Παράδειγμα: έναρξη αιτήματος δικτύου στο κλικ κουμπιού — scope.launch { viewModel.loadData() }.

Jetpack Compose εναντίον View System: σύγκριση

Η επιλογή μεταξύ Compose και View System — το κύριο αρχιτεκτονικό ερώτημα του προγραμματιστή Android το 2026. Και οι δύο τεχνολογίες υποστηρίζονται από την Google, αλλά το Compose είναι η κύρια κατεύθυνση στην οποία η Google διαθέτει πόρους. Το View System λαμβάνει μόνο κρίσιμες διορθώσεις και δεν εξελίσσεται. Η διαφορά εκδηλώνεται στη σύνταξη, τη διαχείριση κατάστασης, την απόδοση και τον χρόνο ανάπτυξης.

ΠτυχήJetpack ComposeView System
Περιγραφή UIΣυναρτήσεις Kotlin @ComposableXML + Activity/Fragment
ΚατάστασηmutableStateOf, StateFlow, αυτόματη ανασχεδίασηfindViewById, χειροκίνητα: setText, notifyDataSetChanged
ΑπόδοσηIntelligent recomposition, απόδοση CanvasΙεραρχία View, measure/layout/draw
Κινήσειςanimate*AsState, AnimatedVisibility, ενσωματωμένεςValueAnimator, ObjectAnimator, Transition
ΣυμβατότηταminSdk 21, γέφυρες ComposeView/AndroidViewΌλες οι εκδόσεις
Μέγεθος APK+3–5 MB για ComposeΧωρίς πρόσθετο κόστος

Για νέα έργα η Google συνιστά το Jetpack Compose ως πρότυπο ανάπτυξης UI. Το View System παραμένει για υποστήριξη κώδικα που γράφτηκε πριν από το 2021 και περιπτώσεις όπου απαιτείται ελάχιστο μέγεθος APK (π.χ. για αναδυόμενες αγορές με συσκευές εισόδου). Compose μειώνει τον όγκο κώδικα UI κατά 30–50% σε σύγκριση με το View System χάρη στη δηλωτική σύνταξη και τις ενσωματωμένες κινήσεις.

Συχνές ερωτήσεις

Μπορώ να χρησιμοποιήσω το Compose σε υπάρχον έργο με View System;

Ναι, μέσω ComposeView σε XML. Προσθέστε εξάρτηση στο Compose και τυλίξτε την οθόνη ή μέρος της σε ComposeView { MyComposable() }. Η μετεγκατάσταση γίνεται οθόνη προς οθόνη.

Γιατί το Composable μου ανασχεδιάζεται πολύ συχνά;

Αιτία — η κατάσταση ανυψώνεται πολύ ψηλά ή χρησιμοποιούνται μεταβλητά αντικείμενα. Διόρθωση: derivedStateOf για παραγόμενα δεδομένα και remember για σταθερές αναφορές.

Πώς να υλοποιήσω μια λίστα στο Compose;

Χρησιμοποιήστε LazyColumn (ανάλογο RecyclerView). Τα στοιχεία δημιουργούνται και επαναχρησιμοποιούνται κατά την κύλιση. Για σύνθετες λίστες με διαφορετικούς τύπους κελιών — LazyColumn { items(items, key = { it.id }) { ... } }.

Πρέπει να μάθω View System πριν από το Compose;

Όχι, μπορείτε να ξεκινήσετε απευθείας με το Compose. Η γνώση του View System βοηθά στην υποστήριξη παλαιού κώδικα, αλλά το Compose είναι ένα αυτόνομο οικοσύστημα με τη δική του τεκμηρίωση και πρότυπα.

Υποστηρίζει το Compose Material 3;

Ναι, το Material 3 — είναι το προεπιλεγμένο θέμα του Compose από το 2023. Συνδέεται μέσω implementation(“androidx.compose.material3:material3”). Το Material 2 θεωρείται ξεπερασμένο.

Σύνοψη

  • Jetpack Compose — declarative UI framework για Android, όπου ολόκληρη η διεπαφή γράφεται σε Kotlin μέσω συναρτήσεων @Composable.
  • Recomposition ανασχεδιάζει αυτόματα μόνο τα στοιχεία που άλλαξαν, εξασφαλίζοντας 120 FPS χωρίς χειροκίνητη βελτιστοποίηση.
  • Κατάσταση διαχειρίζεται μέσω mutableStateOf, collectAsState και StateFlow· το μοτίβο State Hoisting καθιστά τα στοιχεία επαναχρησιμοποιήσιμα.
  • Modifier — αλυσίδα μετασχηματισμών για διαμόρφωση εμφάνισης, κινήσεων και συμπεριφοράς χωρίς κληρονομικότητα κλάσεων.
  • Side Effects (LaunchedEffect, DisposableEffect) απομονώνουν τις παρενέργειες από την ανασύνθεση, αποτρέποντας διαρροές μνήμης και διπλασιασμό αιτημάτων.
  • LazyColumn αντικαθιστά το RecyclerView με λιγότερο κώδικα, και το AnimatedVisibility — σύνθετες αλυσίδες Animator.
  • Η Google συνιστά Compose για όλα τα νέα έργα· το View System παραμένει για υποστήριξη παλαιού κώδικα και περιπτώσεις όπου το ελάχιστο μέγεθος APK είναι κρίσιμο.

Θα αναπτύξουμε μια εφαρμογή για κινητά έτοιμη για χρήση

Η IT Sectr δημιουργεί εφαρμογές iOS και Android για νεοφυείς επιχειρήσεις και επιχειρήσεις από το 2017. Θα σας συμβουλεύσουμε και θα προτείνουμε την καλύτερη λύση.

Συζήτηση έργου

Διαβάστε επίσης