Jetpack Compose в мобільній розробці: що це, ключові поняття та як працює

Автор: IT Sectr Опубліковано: 2026-07-05 Час читання: 10 хв
Jetpack Compose — сучасний UI-фреймворк Android від Google. За даними Google Compose Docs (2025), Compose використовується в 60% нових Android-проєктів. Розуміння @Composable, Recomposition та State Hoisting — основа продуктивної роботи з Compose.

Головне

  • @Composable — анотація для UI-функцій. Компоновка (Composition) — виклик Composable функцій. Recomposition — перезапуск при зміні стану.
  • State Hoisting — підйом стану в батька. State down, events up. Повторно використовувані та тестовані компоненти.
  • remember + mutableStateOf — локальний стан. remember зберігає значення між рекомпозиціями.
  • Modifier — ланцюжок модифікаторів (padding, size, clickable). Порядок важливий.
  • NavController + NavHost — навігація. LaunchedEffect/DisposableEffect — побічні ефекти.

Основи Jetpack Compose (@Composable, Composition, Recomposition)

@Composable — анотація, що перетворює функцію на Composable. Composable функції — будівельні блоки UI. Вони не повертають View, а випромінюють елементи в Composition. Composition — дерево UI, побудоване з викликів Composable функцій. Compose порівнює нове дерево зі старим і оновлює лише змінені частини.

Recomposition

Recomposition — перезапуск Composable функцій при зміні стану. Compose відстежує, які стани читаються в кожній функції. При зміні стану Compose перезапускає лише ті функції, які читають цей стан (Smart Recomposition). Recomposition — оптимістичний: може запускатися кілька разів, тому функції повинні бути чистими (без побічних ефектів). Побічні ефекти — в LaunchedEffect або DisposableEffect. Composable функції не можуть бути suspend. Вони викликаються з інших Composable функцій. Порядок виклику не гарантований (Compose може переупорядковувати).

kotlin
// Приклад Composable з State Hoisting та 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 — декларативне дерево. Recomposition — розумний перезапуск. IT Sectr рекомендує стежити за стабільністю типів — нестабільні типи викликають надлишкову рекомпозицію.

CompositionLocal

CompositionLocal — неявна передача даних в Compose. Аналог @Environment в SwiftUI. CompositionLocalProvider — встановлення значення. current — читання. Використовується для: Theme (MaterialTheme), ContentScale, Density. Статичні CompositionLocal — для конфігурації без змін. Динамічні CompositionLocal — для змінних значень (тем). IT Sectr рекомендує використовувати CompositionLocal для глобальних конфігурацій і явні параметри для даних.

Стан (remember, mutableStateOf, State Hoisting)

remember — зберігає значення між рекомпозиціями. mutableStateOf — створює спостережуваний стан (MutableState<T>). При зміні запускає рекомпозицію. State Hoisting — патерн: стан піднімається в батьківський компонент, дочірній отримує значення + зворотний виклик. State (незмінний) — лише читання. MutableState — читання + запис. rememberSaveable — збереження при обертанні/завершенні процесу.

State Hoisting

State Hoisting — принцип: state down, events up. Стан зберігається в батькові та передається дочірнім компонентам через параметри. Дочірні компоненти повідомляють про зміни через лямбди (зворотний виклик). Переваги: повторне використання, тестованість, єдине джерело істини. Приклад: замість того щоб MyTextField зберігав свій стан, батько зберігає рядок і передає його через value + onValueChange.

Похідний стан

derivedStateOf — обчислюваний стан, перераховується лише при зміні залежностей. Використовується для фільтрації, конвертації, валідації. snapshotFlow — конвертація State в Flow. Використовується для реактивних ланцюжків. collectAsState — збір Flow в State всередині Composable. IT Sectr рекомендує derivedStateOf для обчислюваних значень і snapshotFlow для зв'язування State з корутинами.

Контейнери (Column, Row, Box, LazyColumn)

Column — вертикальний layout (аналог LinearLayout vertical). Row — горизонтальний layout. Box — стековий layout (аналог FrameLayout). LazyColumn — вертикальний scrollable список з lazy loading. LazyRow — горизонтальний scrollable список. Scaffold — основний каркас екрану: TopAppBar, BottomBar, FloatingActionButton, Snackbar. TopAppBar — верхня панель. BottomNavigation — нижня навігація (NavigationBar в Material 3). Modifier — ланцюжок: .fillMaxWidth().padding(8.dp).clickable { }. Порядок модифікаторів важливий — кожен створює новий wrapper.

Оптимізація LazyColumn

LazyColumn — віртуалізований список. Рендерить лише видимі елементи. Оптимізація: 1) key — унікальний ключ для item, 2) contentType — групування item за типом, 3) itemContent — мінімізація recomposition всередині item, 4) LazyVerticalGrid / LazyHorizontalGrid — для сіток. LazyLayout — кастомний lazy layout. Paging 3 + Compose — пагінація через collectAsLazyPagingItems. IT Sectr рекомендує key(item) для всіх LazyColumn для передбачуваної рекомпозиції.

Navigation Compose — бібліотека для навігації. NavController — управління стеком destination'ів. NavHost — контейнер для графа навігації. composable("route") — реєстрація destination. navController.navigate("route") — перехід. popBackStack() — повернення. Аргументи: composable("detail/{id}", arguments = listOf(navArgument("id") { type = NavType.StringType })). Deep linking через intentFilter. BottomNavigation — інтеграція з NavController: NavBarItem → navigate + popUpTo.

Множинні back stacks — окремі back stack для кожної вкладки BottomNavigation. SavedStateHandle — збереження аргументів при завершенні процесу. NavArgs — типобезпечні аргументи (Kotlin 2.0+). Deep links — URL-схеми для зовнішніх посилань. Predictive back gesture (Android 14+) — підтримка жесту назад з попереднім переглядом. IT Sectr рекомендує використовувати NavArgs для типобезпеки та множинні back stacks для BottomNavigation.

Ефекти (LaunchedEffect, DisposableEffect)

LaunchedEffect — запуск suspend-блоку в Composition. Скасовується при виході з Composition. Перезапускається при зміні keys. Використовується для: завантаження даних, таймерів, анімацій. DisposableEffect — для ресурсів, що потребують cleanup: onDispose { } — відписка від listener'ів, закриття з'єднань. SideEffect — синхронний ефект (кожна рекомпозиція). Використовується для: логування, синхронізації з non-Compose кодом. IT Sectr рекомендує LaunchedEffect для завантаження даних і DisposableEffect для cleanup.

Параметр Jetpack Compose SwiftUI
Опис UI@Composable функція + ModifierView Protocol + @ViewBuilder
Станremember + mutableStateOf@State, @StateObject
Підйом стануState Hoisting@Binding
СписокLazyColumnList
НавігаціяNavController + NavHostNavigationStack (iOS 16+)
ЕфектиLaunchedEffect, DisposableEffect.task{}, .onAppear{}
LayoutColumn, Row, BoxVStack, HStack, ZStack

Compose — функція + модифікатор. SwiftUI — struct + модифікатор. Концепції схожі, синтаксис різний. IT Sectr рекомендує вивчати обидва фреймворки — розуміння одного полегшує вивчення іншого.

Патерни ефектів

rememberCoroutineScope — доступ до CoroutineScope поза LaunchedEffect (наприклад, при натисканні кнопки). snapshotFlow — конвертація State в Flow для ланцюжків. produceState — конвертація non-Compose джерела в State. animateFloatAsState та animateColorAsState — анімації через ефекти. IT Sectr рекомендує rememberCoroutineScope для подій UI і LaunchedEffect для автоматичного завантаження.

Темізація (MaterialTheme, Material3)

MaterialTheme — глобальна тема Compose. Кольори, типографіка, форми. MaterialTheme { } — обгортка всього застосунку. Material3 (M3) — дизайн-система Google 2023+. Dynamic Colors — адаптація під шпалери (Android 12+). TextStyle — конфігурація тексту: fontSize, fontWeight, lineHeight. Shape — заокруглення. Elevation — тіні. IT Sectr рекомендує Material3 за замовчуванням і Dynamic Colors для сучасних пристроїв.

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() }
}

Анімації (animate*, AnimatedVisibility)

animateFloatAsState — анімація Float значення. animateColorAsState — анімація кольору. animateDpAsState — анімація розміру. AnimatedVisibility — поява/зникнення з .animateEnterExit(). AnimatedContent — анімація при зміні контенту (crossfade, slide). updateTransition — анімація на основі enum стану. Animatable — кастомна анімація через Animatable інтерфейс. IT Sectr рекомендує AnimatedVisibility для списків і AnimatedContent для зміни екранів.

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()
        )
    }
}

Тестування (Compose UI Test)

Compose UI Test — тестування Compose-екранів. createComposeRule() — правило JUnit. setContent { } — встановлення Composable. onNodeWithText, onNodeWithTag, onNodeWithContentDescription — пошук елементів. performClick, performTextInput, performScrollTo — дії. assertIsDisplayed, assertTextEquals — перевірки. Semantics — дерево Semantics для доступності та тестів. IdlingResource — очікування асинхронних операцій. Screenshot tests — Papercuts, Roborazzi. IT Sectr рекомендує UI тести для кожного екрану та Unit тести для ViewModel.

WindowSizeClass — адаптація під розмір екрану (Compact, Medium, Expanded). Пов'язаний з Material3 responsive layouts. Використовується в Adaptive Navigation Suite для автоматичної зміни BottomNavigation на NavigationRail. IT Sectr рекомендує WindowSizeClass для планшетної та десктопної адаптації Compose застосунків.

Paging 3 + Compose — бібліотека пагінації від Google. PagingData — потік сторінок. PagingConfig — налаштування (pageSize, prefetchDistance). collectAsLazyPagingItems() — збір в Compose. PagingSource — кастомний джерело. RemoteMediator — гібридне завантаження (мережа + БД). Paging 3 — стандарт для списків з нескінченною прокруткою в Compose.

Часті запитання

Що таке @Composable в Jetpack Compose?

@Composable — анотація для UI-функцій. Виклики Composable функцій утворюють Composition. Recomposition — перезапуск при зміні стану.

Що таке State Hoisting в Compose?

State Hoisting — підйом стану в батька. State down, events up. Повторно використовувані та тестовані компоненти.

Що таке Recomposition в Jetpack Compose?

Recomposition — перезапуск Composable функцій при зміні стану. Smart Recomposition — мінімальний набір функцій.

Як працюють NavController та NavHost?

NavController — стек destination'ів. NavHost — контейнер графа. composable("route") — реєстрація. navigate() — перехід.

У чому різниця між LaunchedEffect та DisposableEffect?

LaunchedEffect — suspend-блок з автоматичним скасуванням. DisposableEffect — ресурси з onDispose очищенням.

Підсумки

  • @Composable — UI-функції. Composition — дерево UI. Recomposition — розумний перезапуск.
  • remember + mutableStateOf — локальний стан. rememberSaveable — при обертанні.
  • State Hoisting — state down, events up. Основа повторно використовуваних компонентів.
  • Modifier — ланцюжок (порядок важливий). Column, Row, Box — базові контейнери.
  • LazyColumn — ефективний список. Scaffold — каркас екрану (TopBar, BottomBar, FAB).
  • NavController + NavHost — навігація. composable() — маршрути. navigate() — переходи.
  • LaunchedEffect — асинхронні ефекти. DisposableEffect — очищення. SideEffect — синхронний.

Ми розробимо мобільний застосунок під ключ

IT Sectr створює застосунки для iOS та Android для стартапів і бізнесу з 2017 року. Ми проконсультуємо вас і запропонуємо найкраще рішення.

Обговорити проект