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 изграђен на принципима реактивног програмирања. Уместо 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 адаптера.
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 — анотација која претвара обичну Kotlin функцију у градивни блок UI-ја. Composable функције могу да позивају друге Composable функције, формирајући стабло компонената. За разлику од View-а, Composable функције подразумевано немају стање — оне су stateless и прецртавају се при свакој промени улазних параметара или State-а. Компајлер (Compose Compiler) трансформише @Composable функције у код који може бити прекинут и настављен (positional memoization) — ово омогућава Compose-у да поново покреће само измењене делове без потпуног преправљања стабла.
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 у 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.
@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 — функција Compose-а која кешира вредност између рекомпозиција. Без remember-а, свако поновно покретање Composable функције креира ново стање (mutableStateOf) — то квари логику апликације: при ротацији екрана или промени родитељског State-а, бројач се ресетује. remember прима ламбда-калкулатор и израчунава вредност само при првој композицији; при наредним враћа кеширани резултат. За ресетовање кеша користите remember(key) — кључ одређује када поново израчунати вредност. remember(key1, key2) поново израчунава при промени било ког кључа. За дуготрајна стања (која преживљавају ротацију екрана) користите rememberSaveable — аналог remember-а са чувањем у Bundle-у кроз SavedStateHandle.
@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 — непроменљиви објекат-контејнер који имплементира образац Builder за подешавање изгледа, понашања и распореда Composable компонената. Сваки позив методе Modifier (.padding(), .width(), .clickable(), .background()) враћа нови Modifier са додатим елементом. Редослед модификатора је важан: .padding(16.dp).clickable { } — размак се примењује пре руковаоца кликом, clickable прати целу област узимајући у обзир размак. .clickable { }.padding(16.dp) — кликабилна је цела област пре размака, размак помера садржај ка унутра. Modifier подржава прилагођене имплементације кроз then(otherModifier) и compositionLocal за приступ родитељским подешавањима.
@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 — образац подизања стања из Composable функције у њеног позиваоца, чинећи функцију stateless. Stateless компонента прима податке и callback-ове кроз параметре, не поседујући сопствени State. Ово повећава могућност поновне употребе и тестирања: компонента се може позвати са различитим State-има и тестирати у preview-у. Google препоручује архитектуру: ViewModel + StateFlow (или MutableStateFlow) + collectAsState() у Compose-у. ViewModel подиже стање на ниво екрана, Compose приказује. Споредни ефекти (LaunchedEffect, DisposableEffect) обрађују једнократне догађаје.
| Компонента | Одговорност | Технологија |
|---|---|---|
| ViewModel | Чување State-а, пословна логика | StateFlow, MutableStateFlow |
| Screen Composable | Организација екрана, State hoisting | collectAsState(), Scaffold, LazyColumn |
| Stateless Component | UI без стања, чисто приказивање | @Composable parametri + lambde |
| Side Effect | Једнократне акције (snackbar, навигација) | LaunchedEffect, SnackbarHostState |
Често постављана питања
XML изгледи су императивни: LayoutInflater учитава XML, findViewById проналази View, програмер ручно ажурира текст/листе. Compose је декларативан: UI се описује Kotlin @Composable функцијама, а фрејмворк аутоматски прецртава само измењене делове при промени State-а. Compose смањује обим UI кода за 30–50% и не користи XML.
Да, Google пружа Navigation Compose — библиотеку за декларативну навигацију између екрана. NavController управља стеком рута, composable() региструје екране, navArgument преноси параметре. Алтернативе: Voyager (заједница) и Decompose (Badoo). Navigation Compose је званични стандард са подршком за deep links и type-safe аргументе.
Modifier — непроменљиви контејнер образаца стилизовања (padding, size, clickable, background, border, clip) који се примењују на Composable компоненте. Сваки позив враћа нови Modifier са додатим елементом. Редослед је важан: .padding().clickable() примењује размак пре клика, .clickable().padding() — обрнуто. Modifier је основни начин прилагођавања Compose компонената.
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-ом.
Google пружа Compose UI Test — библиотеку за тестирање на JVM (Desktop) и емулатору. Главне функције: composeTestRule.setContent { } за приказивање компоненте, onNodeWithText() за проналажење елемената, performClick()/performTextInput() за акције. Espresso тестови су компатибилни са Compose-ом кроз ComposeTestRule, али Compose UI Test је пожељнији и бржи приступ.
Завршне напомене
Развићемо мобилну апликацију под кључ
IT Sectr креира iOS и Android апликације за стартапе и предузећа од 2017. године. Саветоваћемо вас и предложити најбоље решење.
Прочитајте такође