Первый экран в Jetpack Compose — шаг за шагом

Коротко: чтобы начать с Jetpack Compose — включите Compose в Gradle, в Activity вызовите setContent { … }, а UI описывайте функциями с аннотацией @Composable. Ниже — минимальная настройка и рабочий пример экрана с TopAppBar, LazyColumn и FloatingActionButton, который можно вставить в проект и запустить.

Создание и базовая настройка проекта

  1. Создайте проект в Android Studio (Kotlin, Empty Activity).
  2. В модуле app включите Compose в android { buildFeatures { compose true } } и используйте Compose BOM. Пример зависимостей (Groovy):
plugins { id 'com.android.application'; id 'org.jetbrains.kotlin.android' }

android {
    compileSdk 34
    defaultConfig { minSdk 21; targetSdk 34 }
    buildFeatures { compose true }
    composeOptions { kotlinCompilerExtensionVersion = "1.5.15" }
}

dependencies {
    def composeBom = platform("androidx.compose:compose-bom:2026.01.01")
    implementation composeBom
    implementation "androidx.compose.material3:material3"
    implementation "androidx.activity:activity-compose"
    implementation "androidx.lifecycle:lifecycle-viewmodel-compose"
}

Используйте Compose BOM, чтобы версии библиотек оставались совместимыми.

Пример: полный экран (AppBar + список + FAB)

В Activity используйте setContent { FirstScreen() }. Ниже — компактный пример composable и простого ViewModel (StateFlow).

// MainActivity.kt (в onCreate)
setContent { FirstScreen() }

// FirstScreen.kt
@Composable
fun FirstScreen(viewModel: MainViewModel = viewModel()) {
    val items by viewModel.items.collectAsState()

    Scaffold(
        topBar = { SmallTopAppBar(title = { Text("Мой экран") }) },
        floatingActionButton = {
            FloatingActionButton(onClick = { viewModel.addItem() }) {
                Icon(Icons.Default.Add, contentDescription = "Add")
            }
        }
    ) { padding ->
        LazyColumn(
            modifier = Modifier.padding(padding).fillMaxSize(),
            contentPadding = PaddingValues(8.dp),
            verticalArrangement = Arrangement.spacedBy(8.dp)
        ) {
            items(items) { it ->
                Card(modifier = Modifier.fillMaxWidth().clickable { /* навигация */ }) {
                    Column(Modifier.padding(16.dp)) {
                        Text(it.title, style = MaterialTheme.typography.titleMedium)
                        Spacer(Modifier.height(4.dp))
                        Text(it.subtitle, style = MaterialTheme.typography.bodyMedium)
                    }
                }
            }
        }
    }
}

Простой ViewModel:

class MainViewModel : ViewModel() {
    private val _items = MutableStateFlow<List<ListItem>>(listOf(
        ListItem(1,"Пункт 1","Подпись 1")
    ))
    val items = _items.asStateFlow()

    fun addItem() {
        val id = (_items.value.maxOfOrNull { it.id } ?: 0) + 1
        _items.value = _items.value + ListItem(id, "Пункт $id", "Подпись $id")
    }
}

Объяснение: состояние храните в ViewModel (StateFlow), composable получает данные через collectAsState() — при изменении списка Compose автоматически перерисует UI.

Не держите в rememberSaveable тяжёлые объекты — это для простого UI‑состояния. Для данных используйте ViewModel.

Ключевые концепции и дальнейшие шаги

  • @Composable: функции, рисующие UI; recomposition вызывается при изменении состояния.
  • State & remember: remember/rememberSaveable для локального, ViewModel + StateFlow/LiveData для долгоживущего.
  • Modifier: комбинируйте padding, fillMaxWidth, clickable и т.д.
  • Navigation: для мульти‑экранных приложений используйте navigation-compose с NavHost и отдельной логикой навигации.
  • Theme: настройте MaterialTheme (рекомендуется Material3) для единообразия стилей.

Частые ошибки

  • Неправильные версии библиотек — используйте BOM.
  • Состояние «теряется» при скролле — поднимайте состояние наверх (ViewModel) или используйте rememberSaveable там, где уместно.
  • Preview не отображается — проверьте импорты и перезапустите Android Studio.

FAQ

  • Нужно ли знать XML? Нет: Compose заменяет XML для UI, но знания о старой инфраструктуре полезны.
  • Как тестировать UI? Используйте @Preview для быстрой отладки и ui-test-junit4 для автоматических тестов.
  • Как хранить состояние экрана при повороте? ViewModel сохраняет состояние при конфигурационных изменениях; rememberSaveable удобен для мелких значений.

Итог — включите Compose, опишите UI в @Composable, держите состояние в ViewModel и начните с простого Scaffold + LazyColumn. Могу сгенерировать готовый проект с файлами build.gradle, Activity, ViewModel и темой по запросу.