Jetpack Compose: основе, Composable функције и State

Аутор: IT Sectr Објављено: 2026-02-21 Време читања: 8 мин

Jetpack Compose — модеран декларативни UI фрејмворк компаније Google за Android развој, представљен у стабилној верзији 1.0 у јулу 2021. Compose замењује императивно XML означавање и View систем Kotlin функцијама са анотацијом @Composable. Према Google I/O (2025), Compose се користи у 55% нових пројеката на Android-у, а просечна величина UI кода се смањује за 30–50% у поређењу са XML-ом. Фрејмворк аутоматски прецртава само измењене делове екрана при промени State-а, елиминишући ручно позивање notifyDataSetChanged или findViewById.

Главно

  • Jetpack Compose — декларативни UI фрејмворк компаније Google за Android у Kotlin-у (@Composable функције уместо XML ознака).
  • @Composable — анотација функције која описује део UI-ја, може примати параметре и читати State.
  • State и MutableState — механизам реактивности: при промени State-а, Compose поново покреће (recompose) само зависне Composable функције.
  • remember — функција кеширања вредности између рекомпозиција; без ње State се ресетује при сваком ажурирању.
  • Modifier — ланац подешавања (padding, size, clickable, background) који управља изгледом и понашањем Composable-а.

Шта је Jetpack Compose?

Jetpack Compose — UI фрејмворк компаније Google изграђен на принципима реактивног програмирања. Уместо Activity-ја са XML изгледима, FragmentManager-а и ViewBinding-а, програмер описује интерфејс кроз Kotlin функције са анотацијом @Composable. Compose не користи LayoutInflater — UI су чисте Kotlin функције, компајлиране у бајткод. Фрејмворк се састоји од неколико библиотека: Compose UI (основни компоненти Text, Button, Column, Row), Compose Foundation (Material Design, гестови, Focus), Compose Material3 (Material You са Dynamic Colors) и Compose Runtime (State, Side Effects, Coroutines). Compose ради на Android API 21+ (Android 5.0) и потпуно је компатибилан са постојећим кодом на View/XML-у путем ComposeView-а — AndroidView адаптера.

Compose vs View System

View System (2008) користи хијерархију View објеката са ручним управљањем: програмер креира XML изглед, проналази View путем findViewById-а, имплементира Adapter за RecyclerView и позива notifyDataSetChanged при промени података. Compose описује UI функционално: при промени стања, фрејмворк поново покреће (recompose) само измењене Composable функције, израчунава diff и примењује минималне измене на Canvas. Перформансе Compose-а су упоредиве са View System-ом, а у сценаријима са сложеним листама (LazyColumn) често надмашује RecyclerView прескакањем непотребних елемената кроз key параметар. У IT Sectr-у, Compose се користи за нове модуле Android апликација са minSdk 24+.

Composable функције: градивни блокови UI-ја

@Composable — анотација која претвара обичну Kotlin функцију у градивни блок UI-ја. Composable функције могу да позивају друге Composable функције, формирајући стабло компонената. За разлику од View-а, Composable функције подразумевано немају стање — оне су stateless и прецртавају се при свакој промени улазних параметара или State-а. Компајлер (Compose Compiler) трансформише @Composable функције у код који може бити прекинут и настављен (positional memoization) — ово омогућава Compose-у да поново покреће само измењене делове без потпуног преправљања стабла.

kotlin
import androidx.compose.foundation.layout.*
import androidx.compose.material3.*
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp

@Composable
fun UserProfile(name: String, avatarUrl: String) {
    Row(
        modifier = Modifier
            .fillMaxWidth()
            .padding(16.dp),
        verticalAlignment = Alignment.CenterVertically
    ) {
        AsyncImage(
            model = avatarUrl,
            contentDescription = "User avatar",
            modifier = Modifier.size(48.dp)
        )
        Spacer(modifier = Modifier.width(12.dp))
        Text(
            text = name,
            style = MaterialTheme.typography.titleMedium
        )
    }
}

Функција UserProfile прима name и avatarUrl као параметре, гради ред са аватаром и именом. Modifier.fillMaxWidth() развлачи компоненту на пуну ширину, .padding(16.dp) додаје размаке. MaterialTheme.typography.titleMedium користи системски стил Material 3. При промени параметара name или avatarUrl, Compose поново покреће UserProfile — поновно креирање компоненте са новим вредностима.

State и Recomposition у Jetpack Compose-у

State у Compose-у — било која вредност чија промена изазива рекомпозицију (поновно покретање) зависних @Composable функција. Основни начин је mutableStateOf(), који креира MutableState<T> са подршком за snapshot систем Compose-а. Snapshot — механизам праћења промена: при упису у State, Compose означава тренутни Snapshot као dirty, и планирач рекомпозиције поново покреће само Composable функције које читају тај State. За observable колекције користите mutableStateListOf() и mutableStateMapOf(). Compose подржава State из Lifecycle-Aware компоненти кроз collectAsState() за Kotlin Flow и observeAsState() за LiveData.

kotlin
@Composable
fun LikeButton() {
    var liked by remember { mutableStateOf(false) }
    var count by remember { mutableStateOf(42) }
    
    Button(
        onClick = {
            liked = !liked
            if (liked) count++ else count--
        },
        colors = ButtonDefaults.buttonColors(
            containerColor = if (liked) MaterialTheme.colorScheme.primary
                else MaterialTheme.colorScheme.surfaceVariant
        )
    ) {
        Text("♥ $count")
    }
}

Код креира дугме «Like» са стањем liked (Boolean) и count (Int), ускладиштеним кроз mutableStateOf(). При притиску, liked се обрће, бројач се повећава/смањује — Compose аутоматски поново покреће LikeButton. by delegate омогућава коришћење State-а као обичне променљиве: liked = !liked уместо liked.value = !liked.value. Боја дугмета се реактивно мења између primary (лајковано) и surfaceVariant (није лајковано).

remember: кеширање између рекомпозиција

remember — функција Compose-а која кешира вредност између рекомпозиција. Без remember-а, свако поновно покретање Composable функције креира ново стање (mutableStateOf) — то квари логику апликације: при ротацији екрана или промени родитељског State-а, бројач се ресетује. remember прима ламбда-калкулатор и израчунава вредност само при првој композицији; при наредним враћа кеширани резултат. За ресетовање кеша користите remember(key) — кључ одређује када поново израчунати вредност. remember(key1, key2) поново израчунава при промени било ког кључа. За дуготрајна стања (која преживљавају ротацију екрана) користите rememberSaveable — аналог remember-а са чувањем у Bundle-у кроз SavedStateHandle.

kotlin
@Composable
fun TimerScreen() {
    var seconds by rememberSaveable { mutableStateOf(0) }
    
    LaunchedEffect(Unit) {
        while (true) {
            delay(1000)
            seconds++
        }
    }
    
    Column(
        modifier = Modifier.fillMaxSize().padding(32.dp),
        horizontalAlignment = Alignment.CenterHorizontally
    ) {
        Text(
            text = "Протекло: ${seconds}s",
            style = MaterialTheme.typography.displayMedium
        )
    }
}

rememberSaveable чува seconds при ротацији екрана (промена конфигурације). LaunchedEffect покреће корутину која увећава seconds сваке секунде. При рекомпозицији TimerScreen-а (сваке секунде) seconds се не ресетује захваљујући rememberSaveable-у. Користите обичан remember за стање које не треба да преживи промене конфигурације (нпр. заставице анимације).

Modifier: ланац подешавања Composable-а

Modifier — непроменљиви објекат-контејнер који имплементира образац Builder за подешавање изгледа, понашања и распореда Composable компонената. Сваки позив методе Modifier (.padding(), .width(), .clickable(), .background()) враћа нови Modifier са додатим елементом. Редослед модификатора је важан: .padding(16.dp).clickable { } — размак се примењује пре руковаоца кликом, clickable прати целу област узимајући у обзир размак. .clickable { }.padding(16.dp) — кликабилна је цела област пре размака, размак помера садржај ка унутра. Modifier подржава прилагођене имплементације кроз then(otherModifier) и compositionLocal за приступ родитељским подешавањима.

kotlin
@Composable
fun CardExample() {
    Card(
        modifier = Modifier
            .fillMaxWidth()
            .padding(16.dp)
            .clickable { println("Картица кликнута") },
        elevation = CardDefaults.cardElevation(defaultElevation = 4.dp),
        colors = CardDefaults.cardColors(
            containerColor = MaterialTheme.colorScheme.surfaceVariant
        )
    ) {
        Column(modifier = Modifier.padding(16.dp)) {
            Text("Jetpack Compose", style = MaterialTheme.typography.titleLarge)
            Spacer(modifier = Modifier.height(8.dp))
            Text(
                "Декларативни UI за Android са State и Modifier",
                style = MaterialTheme.typography.bodyMedium
            )
        }
    }
}

CardExample демонстрира ланац Modifier-а: fillMaxWidth + padding + clickable. Card — Material3 компонента са сопственим подешавањима elevation и colors. Угнеждени Column има унутрашњи padding од 16dp. Compose Material3 аутоматски прилагођава боје Dynamic Color-у (Material You) на Android 12+. Card је једна од 30+ уграђених Material3 компоненти у Compose-у.

State hoisting и архитектура Compose-а

State hoisting — образац подизања стања из Composable функције у њеног позиваоца, чинећи функцију stateless. Stateless компонента прима податке и callback-ове кроз параметре, не поседујући сопствени State. Ово повећава могућност поновне употребе и тестирања: компонента се може позвати са различитим State-има и тестирати у preview-у. Google препоручује архитектуру: ViewModel + StateFlow (или MutableStateFlow) + collectAsState() у Compose-у. ViewModel подиже стање на ниво екрана, Compose приказује. Споредни ефекти (LaunchedEffect, DisposableEffect) обрађују једнократне догађаје.

КомпонентаОдговорностТехнологија
ViewModelЧување State-а, пословна логикаStateFlow, MutableStateFlow
Screen ComposableОрганизација екрана, State hoistingcollectAsState(), Scaffold, LazyColumn
Stateless ComponentUI без стања, чисто приказивање@Composable parametri + lambde
Side EffectЈеднократне акције (snackbar, навигација)LaunchedEffect, SnackbarHostState

Често постављана питања

По чему се Jetpack Compose разликује од XML изгледа?

XML изгледи су императивни: LayoutInflater учитава XML, findViewById проналази View, програмер ручно ажурира текст/листе. Compose је декларативан: UI се описује Kotlin @Composable функцијама, а фрејмворк аутоматски прецртава само измењене делове при промени State-а. Compose смањује обим UI кода за 30–50% и не користи XML.

Да ли је потребна посебна библиотека за навигацију у Compose-у?

Да, Google пружа Navigation Compose — библиотеку за декларативну навигацију између екрана. NavController управља стеком рута, composable() региструје екране, navArgument преноси параметре. Алтернативе: Voyager (заједница) и Decompose (Badoo). Navigation Compose је званични стандард са подршком за deep links и type-safe аргументе.

Шта је Modifier у Jetpack Compose-у?

Modifier — непроменљиви контејнер образаца стилизовања (padding, size, clickable, background, border, clip) који се примењују на Composable компоненте. Сваки позив враћа нови Modifier са додатим елементом. Редослед је важан: .padding().clickable() примењује размак пре клика, .clickable().padding() — обрнуто. Modifier је основни начин прилагођавања Compose компонената.

Да ли Compose ради на свим верзијама Android-а?

Jetpack Compose подржава Android API 21+ (Android 5.0 Lollipop) кроз Compose Compiler и Compose BOM. Material 3 (Dynamic Colors) је доступан на Android 12+; на старијим верзијама користи се fallback палета. За нове пројекте Apple препоручује minSdk 24+ (Android 7.0), што је у потпуности покривено Compose-ом.

Како тестирати Compose компоненте?

Google пружа Compose UI Test — библиотеку за тестирање на JVM (Desktop) и емулатору. Главне функције: composeTestRule.setContent { } за приказивање компоненте, onNodeWithText() за проналажење елемената, performClick()/performTextInput() за акције. Espresso тестови су компатибилни са Compose-ом кроз ComposeTestRule, али Compose UI Test је пожељнији и бржи приступ.

Завршне напомене

  • Jetpack Compose — декларативни UI фрејмворк компаније Google за Android са Kotlin @Composable функцијама уместо XML-а (стабилан од 2021).
  • @Composable — анотација која претвара Kotlin функцију у UI компоненту; стабло Composable функција замењује хијерархију View-а.
  • State и mutableStateOf — основа реактивности Compose-а кроз Snapshot систем; рекомпозиција погађа само зависне функције.
  • remember кешира вредност између рекомпозиција; rememberSaveable чува State при променама конфигурације.
  • Modifier — ланац подешавања (padding, size, clickable, background) који формира непроменљиви контејнер; редослед модификатора је важан.
  • State hoisting — образац подизања стања за stateless компоненте; ViewModel + StateFlow + collectAsState() — препоручена архитектура.
  • Material 3 са Dynamic Colors (Android 12+) — стандардна Compose тема са аутоматским прилагођавањем позадини уређаја.

Развићемо мобилну апликацију под кључ

IT Sectr креира iOS и Android апликације за стартапе и предузећа од 2017. године. Саветоваћемо вас и предложити најбоље решење.

Разговарајте о пројекту

Прочитајте такође