Jetpack Compose — это декларативная UI-система, принципиально отличающаяся от императивной View-системы Android. Это не просто замена TextView на Text() — это полностью другой способ мышления и рендеринга UI.
Главное отличие это «Декларативность»
- В View ты говоришь: «найди кнопку и измени текст»
- В Compose ты говоришь: «если стейт такой — покажи такой UI»
Compose как бы говорит: «Если у тебя новый
state, то перерисуй UI так, чтобы он соответствовал ему. Не важно, что было раньше.»
Принципиальные отличия Compose vs View-система
| View-система (imperative) | Jetpack Compose (declarative) | |
|---|---|---|
| Подход к UI | «Создай и потом изменяй» | «Опиши, каким должен быть UI в текущем стейте» |
| UI создаётся | 1 раз (inflate) и потом мутируется | Каждый раз перерисовывается заново |
| Состояние | Сохраняется в ViewModel, LiveData, View | Используется remember, mutableStateOf() |
| Изменения | вручную: view.text = "new" | автоматически: state → recomposition |
| Производительность | Зависит от иерархии View, layout passes | Использует slot table, skipping, smart diffs |
| Жизненный цикл | Сложный: onAttach, onDetach, onMeasure… | Простой: @Composable → recomposition |
| События UI | setOnClickListener, setText() | onClick = {} в декларативном стиле |
Как работает рекомпозиция в Compose
Рекомпозиция — это перерисовка части UI, когда изменилось наблюдаемое состояние. Compose не перерисовывает весь экран, а только те части, где изменился state. За это отвечает Slot table — структура, отслеживающая где и что было вызвано. Compose умеет скипать вызовы, если параметры не изменились (на основе remember, key, derivedStateOf, etc.).
Пример:
@Composable
fun Counter() {
var count by remember { mutableStateOf(0) }
Column {
Text("Clicked $count times")
Button(onClick = { count++ }) {
Text("Click me")
}
}
}
Что происходит при нажатии:
count++меняетState<Int>- Compose замечает, что
countизменился - Вызывает
Counter()заново - Только изменившиеся узлы (т.е.
Text("Clicked...)) будут пересозданы - Кнопка будет пропущена (skipped) — она не зависит от
count