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, Gestures, 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 = "Elapsed: ${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("Card clicked") },
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 має внутрішній відступ 16dp. Compose Material3 автоматично адаптує кольори під Dynamic Color (Material You) на Android 12+. Card — один із 30+ вбудованих Material3-компонентів у Compose.
State hoisting — патерн підйому стану з Composable-функції в її caller, що робить функцію stateless. Stateless-компонент приймає дані та колбеки через параметри, не володіючи 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 параметри + лямбди |
| Side Effect | Одноразові дії (snackbar, navigation) | LaunchedEffect, SnackbarHostState |
Часті запитання
XML-верстка імперативна: LayoutInflater завантажує XML, findViewById знаходить View, розробник вручну оновлює текст/списки. Compose декларативний: UI описується функціями Kotlin @Composable, а фреймворк автоматично перемальовує лише змінені частини при зміні State. Compose скорочує обсяг UI-коду на 30–50% і не використовує XML.
Так, Google надає Navigation Compose — бібліотеку для декларативної навігації між екранами. NavController керує стеком маршрутів, composable() реєструє екрани, navArgument передає параметри. Альтернативи: Voyager (community) та 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-палітра. Для нових проектів Google рекомендує 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 року. Ми проконсультуємо вас і запропонуємо найкраще рішення.
Читайте також