Jetpack Compose: шта је то, кључни појмови и composable функције

Аутор: IT Sectr Објављено: 2026-05-01 Време читања: 9 мин

Jetpack Compose — модеран декларативни алат за изградњу Android интерфејса у Kotlin-у. Програмер описује UI помоћу composable функција, а алат аутоматски прецртава само измењене делове. Према подацима Android Developers (2026), Jetpack Compose ради на Android 5.0 (API 21) и новијим, подржава Material Design 3 и достиже 120 FPS на уређајима средњег сегмента захваљујући сопственом систему Recomposition — паметном diff алгоритму који ажурира само измењене виџете.

Главне тачке

  • Jetpack Compose — декларативни UI оквир за Android, где се интерфејс гради преко анотираних @Composable функција у Kotlin-у.
  • Recomposition — механизам аутоматског ажурирања само оних компоненти чији су се подаци променили, обезбеђујући 120 FPS.
  • State се управља кроз mutableStateOf, collectAsState и StateFlow — при промени вредности композиција се поново покреће за зависне приказе.
  • Modifier — ланац функција за подешавање размака, величина, позадине, кликова и анимација без наслеђивања класа.
  • Side Effects — LaunchedEffect, DisposableEffect и rememberCoroutineScope — управљају споредним акцијама: тајмери, мрежни захтеви, претплате.

Шта је Jetpack Compose?

Jetpack Compose — декларативни оквир од 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 библиотека. Оквир је компатибилан са постојећим кодом на 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-а.

Слотови и Content Lambda

Composable функције активно користе слотове — trailing lambda, content: @Composable (() -> Unit). Ово омогућава креирање контејнера: Card, Column, Row примају content ламбду, а садржај се уграђује на место слота. 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 model: 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). Све анимације раде на graphics layer-у, не изазивајући додатну композицију.

Side Effects: LaunchedEffect, DisposableEffect, remember

Composable функције не би требало да извршавају споредне акције директно (мрежни захтеви, тајмери, претплате) — one се позивају при свакој рекомпозицији, што би довело до дуплирања захтева. За споредне ефекте Compose пружа породицу Effect функција: LaunchedEffect покреће корутину при уласку у композицију и отказује при изласку, 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 променио — претходна корутина се отказује, нова се покреће са новим userId-јем. Ово елиминише ручно управљање отказивањем захтева. DisposableEffect(Unit) — ефекат са фиксним кључем Unit, активира се при уласку у композицију и позива onDispose при изласку. SensorReader региструје слушаоца и одјављује се при напуштању екрана — без ризика од цурења меморије.

rememberCoroutineScope

Ако корутину треба покренути не при уласку у композицију, већ након догађаја (притиска дугмета), користи се rememberCoroutineScope(). Он враћа CoroutineScope везан за животни циклус Composable-а, не захтева DisposableEffect. Пример: покретање мрежног захтева при клику на дугме — scope.launch { viewModel.loadData() }.

Jetpack Compose vs View System: поређење

Избор између Compose-а и View System-а — главно архитектонско питање Android програмера у 2026. години. Обе технологије подржава Google, али Compose је главни правац у који Google улаже ресурсе. View System добија само критичне исправке и не развија се. Разлика се манифестује у синтакси, управљању стањем, перформансама и времену развоја.

АспектJetpack ComposeView System
Опис UIKotlin @Composable функцијеXML + 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-у. Додајте dependency на 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 — декларативни UI оквир за 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. године. Саветоваћемо вас и предложити најбоље решење.

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

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