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 функция описывает, как должен выглядеть фрагмент интерфейса — текст, кнопка, список. Вместо возврата значения функция эмитирует (emits) 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-кодом внутри контент-блока.

Управление состоянием в 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(). Внутри кастомного модификатора можно использовать layout-измерения (Modifier.layout { measurable, constraints -> ... }), рисование (Modifier.drawWithContent { ... }), жесты (Modifier.pointerInput { ... }). Пример: модификатор для пульсирующей анимации при нажатии — измеряет размер, при клике запускает scale-анимацию через animateFloatAsState.

Для анимаций Compose предоставляет animate*AsState (animateFloatAsState, animateColorAsState, animateDpAsState) — значения анимируются между старым и новым состоянием при изменении. Если нужно анимировать появление/иссчезновение — AnimatedVisibility и AnimatedContent с встроенными переходами (fade, slide, expand). Все анимации работают на graphics layer, не вызывая лишнюю композицию.

Side Effects: LaunchedEffect, DisposableEffect, remember

Composable функции не должны выполнять побочные действия напрямую (сетевые запросы, таймеры, подписки) — они вызываются на каждом рекомпозиции, что приведёт к дублированию запросов. Для побочных эффектов 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 МБ на 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 года. Мы проконсультируем вас и предложим наилучшее решение.

Обсудить проект

Читайте также