Jetpack Compose: co to jest, kluczowe pojęcia i funkcje composable

Autor: IT Sectr Opublikowano: 2026-05-01 Czas czytania: 9 min

Jetpack Compose — to nowoczesny deklaratywny zestaw narzędzi do budowania interfejsów Android w języku Kotlin. Deweloper opisuje UI za pomocą funkcji composable, a zestaw narzędzi automatycznie przerysowuje tylko zmienione części. Według danych Android Developers (2026), Jetpack Compose działa na Android 5.0 (API 21) i nowszych, obsługuje Material Design 3 i osiąga 120 FPS na urządzeniach średniej klasy dzięki własnemu systemowi Recomposition — inteligentnemu algorytmowi diff, aktualizującemu tylko zmienione widżety.

Najważniejsze

  • Jetpack Compose — deklaratywny framework UI dla Androida, gdzie interfejs buduje się za pomocą adnotowanych funkcji @Composable w Kotlinie.
  • Recomposition — mechanizm automatycznej aktualizacji tylko tych komponentów, których dane się zmieniły, zapewniający 120 FPS.
  • State jest zarządzany przez mutableStateOf, collectAsState i StateFlow — po zmianie wartości kompozycja jest restartowana dla zależnych widoków.
  • Modifier — łańcuch funkcji do konfiguracji odstępów, rozmiarów, tła, kliknięć i animacji bez dziedziczenia klas.
  • Side Effects — LaunchedEffect, DisposableEffect i rememberCoroutineScope — zarządzają działaniami pobocznymi: timerami, zapytaniami sieciowymi, subskrypcjami.

Czym jest Jetpack Compose?

Jetpack Compose — to deklaratywny framework od Google do budowania interfejsów użytkownika Android, ogłoszony w 2019 roku, który osiągnął stabilne wydanie w 2021. W przeciwieństwie do starego View System (XML + Activity/Fragment), Compose używa adnotowanych funkcji Kotlin — @Composable. Interfejs opisuje się w całości w Kotlinie: nie ma podziału na XML i kod. To wyeliminowało klasę błędów związanych z niezgodnością id w XML i Kotlinie (type-safe synthetic nie pomagał przy refaktoringu).

Compose jest zbudowany na własnym systemie renderowania — Canvas, niezwiązanym z hierarchią View. Każdy Composable rysuje się bezpośrednio na Canvas, omijając onMeasure/onDraw View System. To daje wzrost wydajności na złożonych ekranach: w testach Google (2023) ekran na Compose z 200 elementami renderował się o 40% szybciej niż analogiczny na RecyclerView + ViewHolder.

Minimalne wymagania i kompatybilność

Do pracy Compose wymaga minSdk 21 (Android 5.0) i Kotlin 1.9+. Compose BOM (Bill of Materials) synchronizuje wersje wszystkich bibliotek Compose. Framework jest kompatybilny z istniejącym kodem na View System: Compose wbudowuje się przez ComposeView w XML, a stare View — przez AndroidView w hierarchię Compose. Według danych Google Play Console (2025), Android 5.0+ pokrywa 97% aktywnych urządzeń, więc kompatybilność nie jest ograniczeniem dla większości projektów.

Funkcje Composable i kompozycja

@Composable — to adnotacja, która zamienia zwykłą funkcję Kotlin w blok budulcowy UI. Funkcja Composable opisuje, jak powinien wyglądać fragment interfejsu — tekst, przycisk, lista. Zamiast zwracać wartość, funkcja emituje komponenty UI do kompozycji. Przypomina to generator: każda funkcja dodaje elementy na ekran przy wywołaniu.

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 = "Awatar",
                modifier = Modifier.size(48.dp).clip(CircleShape)
            )
            Spacer(Modifier.width(12.dp))
            Text(
                text = name,
                style = MaterialTheme.typography.titleMedium
            )
        }
    }
}

Funkcja ProfileCard przyjmuje parametry (name, avatarUrl) i emituje Card → Row → AsyncImage + Text. Kompozycja — to drzewo wyemitowanych komponentów w jednym przebiegu. Jeśli parametry się nie zmieniły, Compose pomija wywołanie funkcji (recomposition skip). Jeśli zmienił się tylko name, wywołany zostanie tylko Text, pozostałe elementy nie zostaną przerysowane. Taki intelligent recomposition — kluczowa zaleta wydajnościowa Compose w porównaniu z ręczną optymalizacją View System.

Slot i Content Lambda

Funkcje Composable aktywnie używają slotów — trailing lambda, content: @Composable (() -> Unit). Pozwala to tworzyć kontenery: Card, Column, Row przyjmują lambdę content, a zawartość wbudowuje się w miejsce slotu. Slot API zastąpił atrybuty XML typu android:layout_gravity — teraz położenie elementów podrzędnych określa się kodem Kotlin wewnątrz bloku content.

Zarządzanie stanem w Compose

Stan w Compose — to dowolna wartość, która może zmieniać się w czasie. Gdy stan się zmienia, Compose planuje recomposition dla wszystkich komponentów czytających ten stan. Mechanizm przypomina React hooks: mutableStateOf zwraca MutableState, odczyt .value automatycznie subskrybuje bieżącą kompozycję na zmiany.

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

    Column(modifier = Modifier.padding(16.dp)) {
        Text("Naciśnięto: $count")
        Button(onClick = { count++ }) {
            Text("Zwiększ")
        }
    }
}

@Composable
fun UserScreen(viewModel: UserViewModel) {
    val userName by viewModel.userName.collectAsState()
    Text("Użytkownik: $userName")
}

remember przechowuje wartość między rekompozycjami — w przeciwnym razie mutableStateOf byłby tworzony od nowa przy każdej aktualizacji UI. collectAsState() konwertuje StateFlow z ViewModel na stan kompatybilny z Compose. Zalecenie — do stanu ekranowego używać ViewModel z StateFlow, do lokalnego (np. rozwinięta karta) — mutableStateOf. To rozdzielenie odpowiada zasadzie komponentów „inteligentne/głupie".

State Hoisting

State Hoisting — wzorzec wynoszenia stanu z komponentu podrzędnego do nadrzędnego. Rodzic przekazuje wartość i callback przez parametry, podrzędny wywołuje callback przy zmianie. Rodzic przechowuje mutableStateOf, podrzędny — tylko parametry. To czyni komponent wielokrotnego użytku i testowalnym: ten sam TextField można użyć z dowolnym źródłem danych.

Modifier — konfiguracja wyglądu

Modifier — to obiekt opisujący transformacje Composable: rozmiar, odstępy, tło, obsługę kliknięć, animację, przewijanie. Modyfikatory stosuje się przez łańcuch wywołań: Modifier.fillMaxWidth().padding(16.dp).background(Color.Blue).clickable { }. Każde wywołanie zwraca nowy Modifier z dodaną właściwością — bez mutacji oryginalnego obiektu.

Kolejność modyfikatorów jest ważna. Modifier.padding(16.dp).background(Color.Blue) koloruje obszar z odstępem. Modifier.background(Color.Blue).padding(16.dp) koloruje wewnętrzny prostokąt, a odstęp pozostaje przezroczysty. Mechanika przypomina CSS box model: padding → background działa jak margin + background; background → padding — jak background + padding wewnątrz. Deweloperowi wystarczy zapamiętać: padding najpierw = zewnętrzny odstęp, padding potem = wewnętrzny.

Niestandardowe modyfikatory

Jeśli wbudowanych modyfikatorów nie wystarcza, tworzy się niestandardowy przez Modifier.composed { ... } lub Modifier.then(). Wewnątrz niestandardowego modyfikatora można użyć pomiarów layoutu (Modifier.layout { measurable, constraints -> ... }), rysowania (Modifier.drawWithContent { ... }), gestów (Modifier.pointerInput { ... }). Przykład: modyfikator do pulsującej animacji przy naciśnięciu — mierzy rozmiar, przy kliknięciu uruchamia animację skalowania przez animateFloatAsState.

Do animacji Compose udostępnia animate*AsState (animateFloatAsState, animateColorAsState, animateDpAsState) — wartości animują się między starym a nowym stanem przy zmianie. Jeśli potrzebna jest animacja pojawiania/znikania — AnimatedVisibility i AnimatedContent z wbudowanymi przejściami (fade, slide, expand). Wszystkie animacje działają na graphics layer, nie powodując zbędnej kompozycji.

Side Effects: LaunchedEffect, DisposableEffect, remember

Funkcje Composable nie powinny wykonywać działań pobocznych bezpośrednio (zapytania sieciowe, timery, subskrypcje) — są wywoływane przy każdej rekompozycji, co prowadziłoby do duplikowania zapytań. Do efektów pobocznych Compose udostępnia rodzinę funkcji Effect: LaunchedEffect uruchamia korutynę przy wejściu do kompozycji i anuluje przy wyjściu, DisposableEffect — dla zasobów wymagających jawnego czyszczenia (czujniki, 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("Wartość: $sensorValue")
}

@Composable
fun UserGreeting(userId: String) {
    LaunchedEffect(userId) {
        val profile = api.fetchProfile(userId)
        // aktualizacja stanu
    }
}

LaunchedEffect(userId) restartuje się, jeśli userId się zmienił — poprzednia korutyna jest anulowana, nowa uruchamia się z nowym userId. To eliminuje ręczne zarządzanie anulowaniem zapytań. DisposableEffect(Unit) — efekt ze stałym kluczem Unit, uruchamia się przy wejściu do kompozycji i wywołuje onDispose przy wyjściu. SensorReader rejestruje słuchacza i wypisuje się przy opuszczeniu ekranu — bez ryzyka wycieku.

rememberCoroutineScope

Jeśli korutynę trzeba uruchomić nie przy wejściu do kompozycji, a po zdarzeniu (naciśnięcie przycisku), używa się rememberCoroutineScope(). Zwraca CoroutineScope powiązany z cyklem życia Composable, nie wymagający DisposableEffect. Przykład: uruchomienie zapytania sieciowego przy kliknięciu przycisku — scope.launch { viewModel.loadData() }.

Jetpack Compose vs View System: porównanie

Wybór między Compose a View System — główne pytanie architektoniczne dewelopera Android w 2026 roku. Obie technologie są wspierane przez Google, ale Compose jest głównym kierunkiem, na który Google przeznacza zasoby. View System otrzymuje tylko krytyczne poprawki i nie rozwija się. Różnica przejawia się w składni, zarządzaniu stanem, wydajności i czasie tworzenia.

AspektJetpack ComposeView System
Opis UIFunkcje Kotlin @ComposableXML + Activity/Fragment
StanmutableStateOf, StateFlow, automatyczne przerysowaniefindViewById, ręcznie: setText, notifyDataSetChanged
WydajnośćIntelligent recomposition, CanvasHierarchia View, measure/layout/draw
Animacjeanimate*AsState, AnimatedVisibility, wbudowaneValueAnimator, ObjectAnimator, Transition
KompatybilnośćminSdk 21, mosty ComposeView/AndroidViewWszystkie wersje
Rozmiar APK+3–5 MB na ComposeBez narzutów

Do nowych projektów Google zaleca Jetpack Compose jako standard tworzenia UI. View System pozostaje do wsparcia kodu napisanego przed 2021 rokiem oraz przypadków, gdy wymagany jest minimalny rozmiar APK (np. dla rynków rozwijających się z urządzeniami podstawowymi). Compose zmniejsza objętość kodu UI o 30–50% w porównaniu z View System dzięki deklaratywnej składni i wbudowanym animacjom.

Często zadawane pytania

Czy można używać Compose w istniejącym projekcie na View System?

Tak, przez ComposeView w XML. Dodaj dependency na Compose i owiń ekran lub jego część w ComposeView { MyComposable() }. Migracja jest ekranowa.

Dlaczego mój Composable przerysowuje się zbyt często?

Przyczyna — stan jest podnoszony zbyt wysoko lub używane są mutowalne obiekty. Naprawa: derivedStateOf dla danych pochodnych i remember dla stabilnych referencji.

Jak zaimplementować listę w Compose?

Użyj LazyColumn (odpowiednik RecyclerView). Elementy są tworzone i ponownie wykorzystywane podczas przewijania. Dla złożonych list z różnymi typami komórek — LazyColumn { items(items, key = { it.id }) { ... } }.

Czy trzeba uczyć się View System przed Compose?

Nie, można zaczynać od razu z Compose. Znajomość View System pomaga przy wsparciu starszego kodu, ale Compose to samodzielny ekosystem z własną dokumentacją i wzorcami.

Czy Compose obsługuje Material 3?

Tak, Material 3 — to standardowy motyw Compose od 2023 roku. Podłącza się przez implementation("androidx.compose.material3:material3"). Material 2 jest uznawany za przestarzały.

Podsumowanie

  • Jetpack Compose — deklaratywny framework UI dla Androida, gdzie cały interfejs pisze się w Kotlinie przez funkcje @Composable.
  • Recomposition automatycznie przerysowuje tylko zmienione komponenty, zapewniając 120 FPS bez ręcznej optymalizacji.
  • Stan jest zarządzany przez mutableStateOf, collectAsState i StateFlow; wzorzec State Hoisting czyni komponenty wielokrotnego użytku.
  • Modifier — łańcuch transformacji do konfiguracji wyglądu, animacji i zachowania bez dziedziczenia klas.
  • Side Effects (LaunchedEffect, DisposableEffect) izolują działania poboczne od rekompozycji, zapobiegając wyciekom i duplikowaniu zapytań.
  • LazyColumn zastępuje RecyclerView z mniejszą ilością kodu, a AnimatedVisibility — złożone łańcuchy Animator.
  • Google zaleca Compose dla wszystkich nowych projektów; View System pozostaje do wsparcia starszego kodu i przypadków, gdy krytyczny jest minimalny rozmiar APK.

Opracujemy aplikację mobilną pod klucz

IT Sectr tworzy aplikacje na iOS i Androida dla startupów i firm od 2017 roku. Doradzimy Ci i zaproponujemy najlepsze rozwiązanie.

Omów projekt

Przeczytaj również