Jetpack Compose — модерен декларативен UI фреймворк от Google за Android разработка, представен в стабилна версия 1.0 през юли 2021 г. Compose замества императивното XML маркиране и View системата с Kotlin функции с анотация @Composable. Според Google I/O (2025), Compose се използва в 55% от новите проекти за Android, а средният размер на UI кода се намалява с 30–50% в сравнение с XML. Фреймворкът автоматично прерисува само променените части на екрана при промяна на State, елиминирайки ръчното извикване на notifyDataSetChanged или findViewById.
Основно
Jetpack Compose — UI фреймворк на Google, изграден върху принципите на реактивното програмиране. Вместо Activity с XML оформления, FragmentManager и ViewBinding, разработчикът описва интерфейса чрез Kotlin функции с анотация @Composable. Compose не използва LayoutInflater — UI са чисти Kotlin функции, компилирани в байткод. Фреймворкът се състои от няколко библиотеки: Compose UI (основни компоненти Text, Button, Column, Row), Compose Foundation (Material Design, Жестове, Фокус), Compose Material3 (Material You с Dynamic Colors) и Compose Runtime (State, Side Effects, Coroutines). Compose работи на Android API 21+ (Android 5.0) и е напълно съвместим с съществуващ View/XML код чрез ComposeView — адаптера AndroidView.
View System (2008) използва йерархия от View обекти с ръчно управление: разработчикът създава XML оформление, намира View чрез findViewById, имплементира Adapter за RecyclerView и извиква notifyDataSetChanged при промяна на данни. Compose описва UI функционално: при промяна на състояние, фреймворкът рестартира (recompose) само променените Composable функции, изчислява diff и прилага минимални промени към Canvas. Производителността на Compose е сравнима с View System, а в сценарии със сложни списъци (LazyColumn) често надминава RecyclerView чрез пропускане на ненужни елементи чрез параметъра key. В IT Sectr, Compose се използва за нови модули на Android приложения с minSdk 24+.
@Composable — анотация, превръщаща обикновена Kotlin функция в градивен блок на UI. Composable функции могат да извикват други Composable функции, образувайки дърво от компоненти. За разлика от View, Composable функциите по подразбиране нямат състояние — те са stateless и се прерисуват при всяка промяна на входните параметри или State. Компилаторът (Compose Compiler) трансформира @Composable функциите в код, който може да бъде прекъснат и възобновен (positional memoization) — това позволява на Compose да рестартира само променените части без пълно преизграждане на дървото.
import androidx.compose.foundation.layout.*
import androidx.compose.material3.*
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
@Composable
fun UserProfile(name: String, avatarUrl: String) {
Row(
modifier = Modifier
.fillMaxWidth()
.padding(16.dp),
verticalAlignment = Alignment.CenterVertically
) {
AsyncImage(
model = avatarUrl,
contentDescription = "User avatar",
modifier = Modifier.size(48.dp)
)
Spacer(modifier = Modifier.width(12.dp))
Text(
text = name,
style = MaterialTheme.typography.titleMedium
)
}
}Функцията UserProfile приема name и avatarUrl като параметри, изгражда ред с аватар и име. Modifier.fillMaxWidth() разтяга компонента на пълна ширина, .padding(16.dp) добавя разстояния. MaterialTheme.typography.titleMedium използва системния стил на Material 3. При промяна на параметрите name или avatarUrl, Compose рестартира UserProfile — повторно създаване на компонента с нови стойности.
State в Compose — всяка стойност, чиято промяна причинява рекомпозиция (рестартиране) на зависими @Composable функции. Основният начин е mutableStateOf(), създаващ MutableState<T> с поддръжка на snapshot системата на Compose. Snapshot — механизъм за проследяване на промени: при запис в State, Compose маркира текущия Snapshot като dirty и планировчикът на рекомпозиция рестартира само Composable функциите, които четат този State. За наблюдаеми колекции използвайте mutableStateListOf() и mutableStateMapOf(). Compose поддържа State от Lifecycle-Aware компоненти чрез collectAsState() за Kotlin Flow и observeAsState() за LiveData.
@Composable
fun LikeButton() {
var liked by remember { mutableStateOf(false) }
var count by remember { mutableStateOf(42) }
Button(
onClick = {
liked = !liked
if (liked) count++ else count--
},
colors = ButtonDefaults.buttonColors(
containerColor = if (liked) MaterialTheme.colorScheme.primary
else MaterialTheme.colorScheme.surfaceVariant
)
) {
Text("♥ $count")
}
}Кодът създава бутон «Like» със състояние liked (Boolean) и count (Int), съхранявани чрез mutableStateOf(). При натискане, liked се обръща, броячът се увеличава/намалява — Compose автоматично рестартира LikeButton. by delegate позволява използването на State като обикновена променлива: liked = !liked вместо liked.value = !liked.value. Цветът на бутона се променя реактивно между primary (харесано) и surfaceVariant (нехаресано).
remember — функция на Compose, кешираща стойността между рекомпозиции. Без remember, всяко рестартиране на Composable функция създава ново състояние (mutableStateOf) — това нарушава логиката на приложението: при завъртане на екрана или промяна на родителски State, броячът се нулира. remember приема ламбда-калкулатор и изчислява стойността само при първата композиция; при следващи връща кеширания резултат. За нулиране на кеша използвайте remember(key) — ключът определя кога да се преизчисли стойността. remember(key1, key2) преизчислява при промяна на който и да е ключ. За дълготрайни състояния (които преживяват завъртане на екрана) използвайте rememberSaveable — аналог на remember със запазване в Bundle чрез SavedStateHandle.
@Composable
fun TimerScreen() {
var seconds by rememberSaveable { mutableStateOf(0) }
LaunchedEffect(Unit) {
while (true) {
delay(1000)
seconds++
}
}
Column(
modifier = Modifier.fillMaxSize().padding(32.dp),
horizontalAlignment = Alignment.CenterHorizontally
) {
Text(
text = "Изминало време: ${seconds}s",
style = MaterialTheme.typography.displayMedium
)
}
}rememberSaveable запазва seconds при завъртане на екрана (промяна на конфигурация). LaunchedEffect стартира корутина, която увеличава seconds всяка секунда. При рекомпозиция на TimerScreen (всяка секунда) seconds не се нулира благодарение на rememberSaveable. Използвайте обикновен remember за състояние, което не трябва да преживява конфигурационни промени (например анимационни флагове).
Modifier — неизменим обект-контейнер, имплементиращ шаблона Builder за настройка на външния вид, поведението и оформлението на Composable компоненти. Всяко извикване на метод на Modifier (.padding(), .width(), .clickable(), .background()) връща нов Modifier с добавен елемент. Редът на модификаторите е важен: .padding(16.dp).clickable { } — разстоянието се прилага преди манипулатора на клик, clickable проследява цялата област като взема предвид разстоянието. .clickable { }.padding(16.dp) — цялата област преди разстоянието е кликаема, разстоянието премества съдържанието навътре. Modifier поддържа персонализирани имплементации чрез then(otherModifier) и compositionLocal за достъп до родителски настройки.
@Composable
fun CardExample() {
Card(
modifier = Modifier
.fillMaxWidth()
.padding(16.dp)
.clickable { println("Картата е кликната") },
elevation = CardDefaults.cardElevation(defaultElevation = 4.dp),
colors = CardDefaults.cardColors(
containerColor = MaterialTheme.colorScheme.surfaceVariant
)
) {
Column(modifier = Modifier.padding(16.dp)) {
Text("Jetpack Compose", style = MaterialTheme.typography.titleLarge)
Spacer(modifier = Modifier.height(8.dp))
Text(
"Декларативен UI за Android с State и Modifier",
style = MaterialTheme.typography.bodyMedium
)
}
}
}CardExample демонстрира веригата на Modifier: fillMaxWidth + padding + clickable. Card — Material3 компонент със собствени настройки на elevation и colors. Вложеният Column има вътрешно разстояние от 16dp. Compose Material3 автоматично адаптира цветовете към Dynamic Color (Material You) на Android 12+. Card е един от 30+ вградени Material3 компонента в Compose.
State hoisting — шаблон за повдигане на състояние от Composable функция към нейния извикващ, правейки функцията stateless. Stateless компонентът приема данни и callback-ове чрез параметри, без да притежава собствено State. Това увеличава възможността за повторна употреба и тестване: компонентът може да бъде извикан с различни State и тестван в preview. Google препоръчва архитектурата: ViewModel + StateFlow (или MutableStateFlow) + collectAsState() в Compose. ViewModel повдига състоянието на ниво екран, Compose показва. Страничните ефекти (LaunchedEffect, DisposableEffect) обработват еднократни събития.
| Компонент | Отговорност | Технология |
|---|---|---|
| ViewModel | Съхранение на State, бизнес логика | StateFlow, MutableStateFlow |
| Screen Composable | Организация на екрана, State hoisting | collectAsState(), Scaffold, LazyColumn |
| Stateless Component | UI без състояние, чисто показване | @Composable параметри + lambди |
| Side Effect | Еднократни действия (snackbar, навигация) | LaunchedEffect, SnackbarHostState |
Често задавани въпроси
XML оформленията са императивни: LayoutInflater зарежда XML, findViewById намира View, разработчикът ръчно обновява текст/списъци. Compose е декларативен: UI се описва с Kotlin @Composable функции, а фреймворкът автоматично прерисува само променените части при промяна на State. Compose намалява обема на UI код с 30–50% и не използва XML.
Да, Google предоставя Navigation Compose — библиотека за декларативна навигация между екрани. NavController управлява стека от маршрути, composable() регистрира екрани, navArgument предава параметри. Алтернативи: Voyager (общност) и Decompose (Badoo). Navigation Compose е официалният стандарт с поддръжка на deep links и type-safe аргументи.
Modifier — неизменим контейнер на стилови шаблони (padding, size, clickable, background, border, clip), прилагани към Composable компоненти. Всяко извикване връща нов Modifier с добавен елемент. Редът е важен: .padding().clickable() прилага разстояние преди клик, .clickable().padding() — обратно. Modifier е основният начин за персонализиране на Compose компоненти.
Jetpack Compose поддържа Android API 21+ (Android 5.0 Lollipop) чрез Compose Compiler и Compose BOM. Material 3 (Dynamic Colors) е достъпен на Android 12+; на по-стари версии се използва резервна палитра. За нови проекти Apple препоръчва minSdk 24+ (Android 7.0), което е напълно покрито от Compose.
Google предоставя Compose UI Test — библиотека за тестване на JVM (Desktop) и емулатор. Основни функции: composeTestRule.setContent { } за визуализиране на компонент, onNodeWithText() за търсене на елементи, performClick()/performTextInput() за действия. Espresso тестовете са съвместими с Compose чрез ComposeTestRule, но Compose UI Test е предпочитаният и по-бърз подход.
Резюме
Ще разработим мобилно приложение под ключ
IT Sectr създава iOS и Android приложения за стартъпи и бизнеси от 2017 г. Ще ви консултираме и ще предложим най-доброто решение.
Прочетете също