Jetpack Compose w rozwoju mobilnym: co to jest, kluczowe pojęcia i jak działa

Autor: IT Sectr Opublikowano: 2026-07-05 Czas czytania: 10 min
Jetpack Compose — nowoczesny framework UI dla Androida od Google. Według Google Compose Docs (2025), Compose jest używany w 60% nowych projektów Android. Zrozumienie @Composable, Recomposition i State Hoisting to podstawa wydajnej pracy z Compose.

Najważniejsze informacje

  • @Composable — adnotacja dla funkcji UI. Composition — wywoływanie funkcji Composable. Recomposition — restart przy zmianie stanu.
  • State Hoisting — podnoszenie stanu do rodzica. State down, events up. Komponenty wielokrotnego użytku i testowalne.
  • remember + mutableStateOf — stan lokalny. remember zachowuje wartość między rekompozycjami.
  • Modifier — łańcuch modyfikatorów (padding, size, clickable). Kolejność ma znaczenie.
  • NavController + NavHost — nawigacja. LaunchedEffect/DisposableEffect — efekty uboczne.

Podstawy Jetpack Compose (@Composable, Composition, Recomposition)

@Composable — adnotacja zmieniająca funkcję w Composable. Funkcje Composable to bloki konstrukcyjne UI. Nie zwracają View, emitują elementy do Composition. Composition — drzewo UI zbudowane z wywołań funkcji Composable. Compose porównuje nowe drzewo ze starym i aktualizuje tylko zmienione części.

Recomposition

Recomposition — restart funkcji Composable przy zmianie stanu. Compose śledzi, które stany są odczytywane w każdej funkcji. Gdy stan się zmienia, Compose restartuje tylko funkcje, które odczytują ten stan (Smart Recomposition). Recomposition jest optymistyczny: może uruchomić się wielokrotnie, więc funkcje muszą być czyste (bez efektów ubocznych). Efekty uboczne umieszcza się w LaunchedEffect lub DisposableEffect. Funkcje Composable nie mogą być suspend. Są wywoływane z innych funkcji Composable. Kolejność wywołań nie jest gwarantowana (Compose może zmienić kolejność).

kotlin
// Przykład Composable z State Hoisting i LazyColumn
@Composable
fun ItemList(
    items: List<String>,
    onItemClick: (String) -> Unit
) {
    LazyColumn(
        modifier = Modifier.fillMaxSize()
    ) {
        items(items) { item ->
            Card(
                modifier = Modifier
                    .fillMaxWidth()
                    .clickable { onItemClick(item) }
                    .padding(8.dp)
            ) {
                Text(
                    text = item,
                    style = MaterialTheme.typography.bodyLarge
                )
            }
        }
    }
}

@Composable
fun MainScreen() {
    var text by remember { mutableStateOf("") }
    val items = listOf("Item 1", "Item 2", "Item 3")

    Scaffold(
        topBar = {
            TopAppBar(title = { Text("Compose App") })
        }
    ) { padding ->
        ItemList(
            items = items,
            onItemClick = { selected -> text = selected }
        )
    }
}

Composition — deklaratywne drzewo. Recomposition — inteligentny restart. IT Sectr zaleca monitorowanie stabilności typów — niestabilne typy powodują nadmierną rekompozycję.

CompositionLocal

CompositionLocal — niejawne przekazywanie danych w Compose. Analogia do @Environment w SwiftUI. CompositionLocalProvider — ustawianie wartości. current — odczyt. Używane do: Theme (MaterialTheme), ContentScale, Density. Statyczny CompositionLocal — do konfiguracji bez zmian. Dynamiczny CompositionLocal — do zmiennych wartości (motywów). IT Sectr zaleca używanie CompositionLocal dla konfiguracji globalnych i jawnych parametrów dla danych.

Stan (remember, mutableStateOf, State Hoisting)

remember — zachowuje wartość między rekompozycjami. mutableStateOf — tworzy obserwowalny stan (MutableState<T>). Po zmianie wyzwala rekompozycję. State Hoisting — wzorzec: stan jest podnoszony do komponentu rodzica, dziecko otrzymuje wartość + callback. State (niezmienny) — tylko do odczytu. MutableState — odczyt + zapis. rememberSaveable — utrzymuje się podczas obrotu/śmierci procesu.

State Hoisting

State Hoisting — zasada: state down, events up. Stan jest przechowywany w rodzicu i przekazywany do komponentów potomnych przez parametry. Komponenty potomne zgłaszają zmiany przez lambdy (callback). Zalety: wielokrotnego użytku, testowalność, pojedyncze źródło prawdy. Przykład: zamiast MyTextField przechowywał własny stan, rodzic przechowuje string i przekazuje go przez value + onValueChange.

Stan pochodny

derivedStateOf — stan obliczany, przeliczany tylko przy zmianie zależności. Używane do filtrowania, konwersji, walidacji. snapshotFlow — konwersja State na Flow. Używane do reaktywnych łańcuchów. collectAsState — zbieranie Flow w State wewnątrz Composable. IT Sectr zaleca derivedStateOf dla wartości obliczanych i snapshotFlow do łączenia State z korutynami.

Kontenery (Column, Row, Box, LazyColumn)

Column — układ pionowy (analogia do LinearLayout vertical). Row — układ poziomy. Box — układ warstwowy (analogia do FrameLayout). LazyColumn — pionowa przewijana lista z leniwym ładowaniem. LazyRow — pozioma przewijana lista. Scaffold — główny szkielet ekranu: TopAppBar, BottomBar, FloatingActionButton, Snackbar. TopAppBar — górny pasek. BottomNavigation — dolna nawigacja (NavigationBar w Material 3). Modifier — łańcuch: .fillMaxWidth().padding(8.dp).clickable { }. Kolejność modyfikatorów ma znaczenie — każdy tworzy nowy wrapper.

Optymalizacja LazyColumn

LazyColumn — lista wirtualizowana. Renderuje tylko widoczne elementy. Optymalizacja: 1) key — unikalny klucz dla elementu, 2) contentType — grupowanie elementów według typu, 3) itemContent — minimalizacja rekompozycji wewnątrz elementu, 4) LazyVerticalGrid / LazyHorizontalGrid — dla siatek. LazyLayout — niestandardowy leniwy układ. Paging 3 + Compose — paginacja przez collectAsLazyPagingItems. IT Sectr zaleca key(item) dla wszystkich LazyColumn dla przewidywalnej rekompozycji.

Navigation Compose — biblioteka nawigacji. NavController — zarządza stosem miejsc docelowych. NavHost — kontener grafu nawigacji. composable("route") — rejestracja miejsca docelowego. navController.navigate("route") — nawigacja. popBackStack() — powrót. Argumenty: composable("detail/{id}", arguments = listOf(navArgument("id") { type = NavType.StringType })). Deep linking przez intentFilter. BottomNavigation — integracja z NavController: NavBarItem → navigate + popUpTo.

Wiele stosów wstecznych — oddzielny stos wsteczny dla każdej karty BottomNavigation. SavedStateHandle — zachowywanie argumentów przy śmierci procesu. NavArgs — bezpieczne typowo argumenty (Kotlin 2.0+). Deep linki — schematy URL dla linków zewnętrznych. Predykcyjny gest wstecz (Android 14+) — obsługa gestu wstecz z podglądem. IT Sectr zaleca używanie NavArgs dla bezpieczeństwa typów i wielu stosów wstecznych dla BottomNavigation.

Efekty (LaunchedEffect, DisposableEffect)

LaunchedEffect — uruchamia blok suspend w Composition. Anulowany przy opuszczaniu Composition. Restartowany przy zmianie keys. Używane do: ładowania danych, timerów, animacji. DisposableEffect — dla zasobów wymagających czyszczenia: onDispose { } — wypisanie się z listenerów, zamknięcie połączeń. SideEffect — efekt synchroniczny (przy każdej rekompozycji). Używane do: logowania, synchronizacji z kodem niekomponowanym. IT Sectr zaleca LaunchedEffect do ładowania danych i DisposableEffect do czyszczenia.

Parametr Jetpack Compose SwiftUI
Opis UIFunkcja @Composable + ModifierView Protocol + @ViewBuilder
Stanremember + mutableStateOf@State, @StateObject
Podnoszenie stanuState Hoisting@Binding
ListaLazyColumnList
NawigacjaNavController + NavHostNavigationStack (iOS 16+)
EfektyLaunchedEffect, DisposableEffect.task{}, .onAppear{}
LayoutColumn, Row, BoxVStack, HStack, ZStack

Compose — funkcja + modyfikator. SwiftUI — struct + modyfikator. Koncepcje są podobne, składnia jest inna. IT Sectr zaleca naukę obu frameworków — zrozumienie jednego ułatwia naukę drugiego.

Wzorce efektów

rememberCoroutineScope — dostęp do CoroutineScope poza LaunchedEffect (np. przy kliknięciu przycisku). snapshotFlow — konwersja State na Flow dla łańcuchów. produceState — konwersja źródła niekomponowanego na State. animateFloatAsState i animateColorAsState — animacje przez efekty. IT Sectr zaleca rememberCoroutineScope dla zdarzeń UI i LaunchedEffect dla automatycznego ładowania.

Motywowanie (MaterialTheme, Material3)

MaterialTheme — globalny motyw Compose. Kolory, typografia, kształty. MaterialTheme { } — otacza całą aplikację. Material3 (M3) — system projektowania Google 2023+. Dynamic Colors — adaptacja do tapety (Android 12+). TextStyle — konfiguracja tekstu: fontSize, fontWeight, lineHeight. Shape — zaokrąglanie narożników. Elevation — cienie. IT Sectr zaleca domyślnie Material3 i Dynamic Colors dla nowoczesnych urządzeń.

kotlin
@Composable
fun AppTheme(content: @Composable () -> Unit) {
    val colorScheme = if (isSystemInDarkTheme()) {
        darkColorScheme(
            primary = Color(0xFFBB86FC),
            secondary = Color(0xFF03DAC6)
        )
    } else {
        lightColorScheme(
            primary = Color(0xFF6200EE),
            secondary = Color(0xFF03DAC6)
        )
    }
    MaterialTheme(
        colorScheme = colorScheme,
        typography = Typography(
            bodyLarge = TextStyle(fontSize = 16.sp)
        )
    ) { content() }
}

Animacje (animate*, AnimatedVisibility)

animateFloatAsState — animuje wartość Float. animateColorAsState — animuje kolor. animateDpAsState — animuje rozmiar. AnimatedVisibility — pokaż/ukryj z .animateEnterExit(). AnimatedContent — animacja przy zmianie treści (crossfade, slide). updateTransition — animacja oparta na stanie enum. Animatable — niestandardowa animacja przez interfejs Animatable. IT Sectr zaleca AnimatedVisibility dla list i AnimatedContent dla przejść między ekranami.

kotlin
@Composable
fun AnimatedCounter(count: Int) {
    val animatedCount by animateFloatAsState(
        targetValue = count.toFloat(),
        animationSpec = spring(
            dampingRatio = Spring.DampingRatioMediumBouncy,
            stiffness = Spring.StiffnessLow
        )
    )

    AnimatedContent(targetState = count) { targetCount ->
        Text(
            text = "$targetCount",
            style = MaterialTheme.typography.displayLarge,
            modifier = Modifier.animateContentSize()
        )
    }
}

Testowanie (Compose UI Test)

Compose UI Test — testowanie ekranów Compose. createComposeRule() — reguła JUnit. setContent { } — ustawienie Composable. onNodeWithText, onNodeWithTag, onNodeWithContentDescription — znajdowanie elementów. performClick, performTextInput, performScrollTo — akcje. assertIsDisplayed, assertTextEquals — asercje. Semantics — drzewo Semantics dla dostępności i testów. IdlingResource — oczekiwanie na operacje asynchroniczne. Testy zrzutów ekranu — Papercuts, Roborazzi. IT Sectr zaleca testy UI dla każdego ekranu i testy jednostkowe dla ViewModel.

WindowSizeClass — adaptacja do rozmiaru ekranu (Compact, Medium, Expanded). Powiązane z responsywnymi układami Material3. Używane w Adaptive Navigation Suite do automatycznej zmiany BottomNavigation na NavigationRail. IT Sectr zaleca WindowSizeClass do adaptacji Compose na tablety i komputery stacjonarne.

Paging 3 + Compose — biblioteka paginacji od Google. PagingData — strumień stron. PagingConfig — ustawienia (pageSize, prefetchDistance). collectAsLazyPagingItems() — zbieranie w Compose. PagingSource — niestandardowe źródło. RemoteMediator — hybrydowe ładowanie (sieć + BD). Paging 3 to standard dla list z nieskończonym przewijaniem w Compose.

Często zadawane pytania

Co to jest @Composable w Jetpack Compose?

@Composable — adnotacja dla funkcji UI. Wywołania funkcji Composable tworzą Composition. Recomposition — restart przy zmianie stanu.

Co to jest State Hoisting w Compose?

State Hoisting — podnoszenie stanu do rodzica. State down, events up. Komponenty wielokrotnego użytku i testowalne.

Co to jest Recomposition w Jetpack Compose?

Recomposition — restart funkcji Composable przy zmianie stanu. Smart Recomposition — minimalny zestaw funkcji.

Jak działają NavController i NavHost?

NavController — stos miejsc docelowych. NavHost — kontener grafu. composable("route") — rejestracja. navigate() — przejście.

Jaka jest różnica między LaunchedEffect a DisposableEffect?

LaunchedEffect — blok suspend z automatycznym anulowaniem. DisposableEffect — zasoby z czyszczeniem onDispose.

Podsumowanie

  • @Composable — funkcje UI. Composition — drzewo UI. Recomposition — inteligentny restart.
  • remember + mutableStateOf — stan lokalny. rememberSaveable — dla obrotu.
  • State Hoisting — state down, events up. Podstawa komponentów wielokrotnego użytku.
  • Modifier — łańcuch (kolejność ważna). Column, Row, Box — podstawowe kontenery.
  • LazyColumn — wydajna lista. Scaffold — szkielet ekranu (TopBar, BottomBar, FAB).
  • NavController + NavHost — nawigacja. composable() — trasy. navigate() — przejścia.
  • LaunchedEffect — efekty asynchroniczne. DisposableEffect — czyszczenie. SideEffect — synchroniczny.

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