Введение: первый шаг занимает пять минут

«Я никогда не работал с Compose. С чего начать?» — с этого вопроса начинается разбор с половиной моих новых учеников. Ответ простой: открыть Android Studio и создать проект. Не читать десять статей, не смотреть три курса — просто создать и посмотреть, что сгенерировалось.

Android Studio — основной инструмент для работы с Compose: в неё встроены шаблоны проектов, умный редактор и предпросмотр UI прямо в IDE, без запуска эмулятора. Сегодня Compose подключается в новый проект буквально выбором шаблона — ручная настройка нужна только если вы добавляете Compose в существующее приложение.

Вся статья — практическая: создаём проект, смотрим, что сгенерировалось, делаем первый экран и запускаем. Если что-то пойдёт не так — последний раздел про частые ошибки, проверьте его первым.

Разберём по шагам: создание проекта, структуру сгенерированного кода, Preview и типичные ошибки, на которых спотыкаются новички.

Создаём проект: шаблон Empty Activity

Запустите Android Studio и выполните следующее:

  1. В окне приветствия выберите New Project (или File → New → New Project, если проект уже открыт).
  2. В списке шаблонов выберите Empty Activity и нажмите Next.
  3. Задайте имя проекта и package, как обычно.
  4. В выпадающем списке Language доступен только Kotlin — Compose работает только с классами, написанными на Kotlin.
  5. В поле Minimum SDK выберите API 21 или выше — это требование Compose.
  6. Нажмите Finish и дождитесь первой синхронизации Gradle.

Почему только Kotlin? Компилятор Compose генерирует код поверх Kotlin-функций, и Java с этим не работает. Если ваш проект на Java — Compose в него придётся внедрять через отдельные Kotlin-модули. Это не ошибка настройки, а архитектурное ограничение.

После создания студия сама подготовит всё необходимое: применит плагин компилятора, подключит зависимости и создаст рабочий экран. Проверить, что Compose «завёлся», можно уже на этом шаге — сборка и запуск проходят без единой правки.

Если студия долго «висит» на первой синхронизации — это нормально: Gradle скачивает зависимости и плагины. Дождитесь завершения, а не перезапускайте проект, иначе скачивание начнётся заново.

Что сгенерировала студия

Откройте MainActivity.kt. Это сердце проекта — Activity, которая вместо setContentView с XML вызывает setContent:

MainActivity.kt
class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            AppTheme {
                Greeting("Android")
            }
        }
    }
}

@Composable
fun Greeting(name: String, modifier: Modifier = Modifier) {
    Text(
        text = "Hello $name!",
        modifier = modifier
    )
}

@Preview(showBackground = true)
@Composable
fun GreetingPreview() {
    AppTheme {
        Greeting("Android")
    }
}

Обратите внимание на три вещи:

  • setContent — точка входа Compose: внутри описывается UI, и это место, куда вы будете добавлять свои экраны.
  • AppTheme — тема проекта из пакета ui.theme: там лежат Color.kt (цвета), Theme.kt (светлая и тёмная схемы) и Type.kt (типографика).
  • @Preview — функция, которая отображается в панели Preview в IDE. Это не код, который выполняется на устройстве, а «картинка» UI для разработчика.

Рядом с MainActivity.kt студия создала build.gradle.kts модуля с уже настроенным Compose: подключён плагин org.jetbrains.kotlin.plugin.compose, включён buildFeatures.compose = true, добавлены Compose BOM и зависимости ui и material3. Версию BOM обновляйте вручную — гайд по обновлению описала сама Google, начиная с настройки зависимостей и компилятора.

Что важно понять

Шаблон Empty Activity — это уже полноценный Compose-проект с правильной настройкой. Ваша задача — не «настроить Compose с нуля», а научиться читать и менять то, что сгенерировано: Activity, тему и Preview.

От шаблона к своему экрану

Первый практический шаг — заменить Greeting("Android") на что-то своё. Например, экран с заголовком и кнопкой счётчика:

MainActivity.kt
setContent {
    AppTheme {
        var count by remember { mutableStateOf(0) }
        Column(
            modifier = Modifier.fillMaxSize().padding(16.dp),
            verticalArrangement = Arrangement.Center
        ) {
            Text(text = "Кликов: $count", style = MaterialTheme.typography.headlineMedium)
            Button(onClick = { count++ }, modifier = Modifier.padding(top = 16.dp)) {
                Text("+1")
            }
        }
    }
}

Здесь уже задействованы три базовые идеи Compose: компоновка (Column с отступами), состояние (remember + mutableStateOf) и тема (MaterialTheme.typography). Соберите проект, покликайте кнопку — и вы прошли путь, на котором спотыкается половина новичков: состояние «завелось» и экран перерисовывается сам.

Дальше логичный шаг — список: замените счётчик на LazyColumn с элементами. А когда список и состояние заработают, добавьте ViewModel и подключите данные из репозитория. Это уже полноценный боевой паттерн, разбор которого есть в статье про MVVM-архитектуру.

Не пытайтесь сразу собрать «всё»: навигацию, анимации, DI. Первая неделя в Compose должна быть простая: один экран, состояние, список. Всё остальное надстроится позже, а фундамент из этих трёх вещей останется навсегда.

Preview и первый запуск

Лучшая часть Compose-разработки — Preview. Справа от редактора (или через вкладку Split) открывается панель, где вы видите, как выглядит @Preview-функция, ещё до запуска приложения. Изменили текст или цвет — картинка обновилась после пересборки модуля. Для быстрых экспериментов это незаменимо: не нужно поднимать эмулятор ради проверки отступа.

@Preview можно настраивать: showBackground = true добавляет фон, widthDp/heightDp задают размер, locale — локаль. Для проверки списков удобно делать несколько Preview-функций — например, одну для пустого состояния, одну для наполненного.

Сам запуск ничем не отличается от обычного: выберите устройство или эмулятор и нажмите Run. Первый запуск может быть медленным — Gradle собирает проект целиком, это нормально.

Частая ошибка новичка: «Preview не обновляется, пока я не нажму Run». Preview обновляется после сборки модуля — нажмите Ctrl+F9 (или значок сборки), а не запускайте всё приложение. И убедитесь, что зависимость ui-tooling-preview на месте: в шаблоне она есть, а при ручной настройке про неё забывают.

Частые проблемы новичков

  • Плагин не применён или версия не совпадает. Ошибка вида «Compose compiler requires Kotlin version» — версия плагина org.jetbrains.kotlin.plugin.compose всегда должна совпадать с версией Kotlin.
  • buildFeatures.compose = true забыли. При ручном подключении Compose в существующий проект без этого флага сборка падает с ошибкой про Compose-функции.
  • Minimum SDK ниже 21. Compose требует API 21+, проект с меньшим уровнем не соберётся.
  • Текст не обновляется при клике. Классика: состояние хранится в обычной переменной вместо remember { mutableStateOf(...) } — рекомпозиция не запускается.
  • Одна Activity на всё. Compose-приложение часто строится на одной Activity с навигацией внутри — не тяните старую привычку открывать новый Activity на каждый экран.

Последний пункт — про архитектуру, а не про Compose. Но именно здесь новички ломают проект: экраны начинают «общаться» через Intent вместо общего состояния, и переписать такое потом больно. Сразу закладывайте ViewModel и однонаправленный поток данных — разбор этого подхода есть в статье про MVVM-архитектуру.

Отдельно про ошибки, которые падают «молча», без красного текста в консоли. Самая коварная — состояние без remember: экран собирается, но ничего не меняется при клике, и новичок думает, что проблема в настройке. Проверка простая: если UI не реагирует на изменения данных — ищите, где состояние объявлено не через remember/mutableStateOf. Вторая похожая — обновление «невидимого» текста: вы меняете значение, а экран показывает старое, потому что composable-функция читает данные из глобальной переменной, а не из состояния. Обе ошибки — из одной семьи: Compose обновляет UI только через наблюдаемое состояние.

Пара слов обо мне: я Рустем Бикбулатов, senior Android-разработчик, провожу технические собеседования и менторю разработчиков, в том числе как ментор Яндекс Практикума. Более 100 учеников и разборов. Когда ученик говорит «у меня нет практики на Compose», я не советую курсы — я даю задачу и разбираю её решение: так за пару недель закрывается то, что люди учат месяцами. Есть диагностика: разбор вашего уровня и план закрытия пробелов.

Хотите получить план роста с практикой на Compose?

Бесплатная диагностика: разберу ваш уровень, дам направление и план — что учить и в каком порядке.

Итоги

Первый Compose-проект — это шаблон Empty Activity в Android Studio и пятнадцать минут внимания:

  • Создание: New Project → Empty Activity → Kotlin → API 21+ → Finish. Всё остальное студия делает сама.
  • Структура: setContent в MainActivity.kt, тема в ui.theme, Preview через @Preview — и уже настроенный build.gradle.kts.
  • Развитие: Preview для быстрых экспериментов, запуск на устройстве, а затем — ViewModel, состояние и навигация.

Главное

Не «настраивайте Compose» — используйте готовый шаблон и меняйте его. Первый экран, состояние через remember, список через LazyColumn — этого достаточно, чтобы почувствовать парадигму.

Если после первого проекта не понятно, что делать дальше, — это нормально, именно на этом этапе большинство и теряется. Напишите в Telegram, разберём вашу ситуацию и составим план подготовки.