Квітневий реліз Jetpack Compose приніс одну з найпомітніших хвиль змін за останній час. Android‑розробник і автор навчального контенту Philipp Lackner у своєму огляді новинок Kotlin‑ та Android‑екосистеми зосередився саме на Compose: від оновленої поведінки корутин у UI‑тестах до нових потужних макетів Grid і Flexbox, експериментального API стилів і покращень прев’ю. Ці зміни не лише додають можливості, а й змушують переглянути звичні підходи до верстки та тестування інтерфейсів.
![]()
Тестування під прицілом: як перехід на StandardTestDispatcher ламає звичні UI‑тести
Одне з найменш помітних на перший погляд, але потенційно найболючіших оновлень у Compose 1.11 стосується саме UI‑тестів. Внутрішні API для тестування інтерфейсу більше не використовують UnconfinedTestDispatcher і переходять на StandardTestDispatcher. Для команд, які активно покривають UI корутинними тестами, це може стати джерелом несподіваних падінь.
Раніше, з UnconfinedTestDispatcher, корутини в тестах запускалися одразу, без додаткового керування віртуальним часом. Будь‑який launch у тестовому корутинному scope фактично стартував миттєво, що створювало ілюзію «простих» асинхронних тестів: написав код, викликав корутину — і результат уже доступний у тому ж тестовому тілі.
StandardTestDispatcher працює інакше. Він ставить завдання в чергу й вимагає явного просування віртуального часу. Корутина, запущена в тесті, не стартує автоматично — її виконання починається лише тоді, коли тест викликає методи на кшталт advanceTimeBy(...) або advanceUntilIdle(). Така модель набагато ближча до реальних умов виконання, де асинхронні операції не гарантують миттєвого завершення.
Це рішення має чітку мотивацію: краще віддзеркалити продакшн‑поведінку й зменшити ризики прихованих race‑condition у тестах. Коли все запускається «без черги», як із UnconfinedTestDispatcher, тести можуть випадково проходити лише тому, що порядок виконання корутин збігся з очікуваннями, хоча в реальному застосунку події можуть відбуватися інакше.
Наслідок для розробників очевидний: оновлення до Compose 1.11 може зламати частину існуючих UI‑тестів. Особливо це стосується тих, що неявно покладалися на «автоматичний» запуск корутин. Тепер доведеться:
переглянути тести, де використовуються корутини в UI‑шарі;
додати явне керування віртуальним часом там, де очікується завершення асинхронних операцій;
усвідомлено розділити ініціалізацію, запуск і перевірку результатів корутин.
З одного боку, це збільшує обсяг роботи при міграції. З іншого — робить тестову базу надійнішою й ближчою до реальної поведінки застосунку, що особливо важливо для складних UI‑сценаріїв із анімаціями, переходами станів і конкурентними оновленнями.
Прев’ю без рутини: PreviewWrapper як спосіб стандартизувати вигляд усіх екранів
Ще одна зміна, яка напряму впливає на щоденну роботу з інтерфейсом, — поява так званих preview wrappers. Compose тепер дозволяє створювати обгортки для прев’ю, що реалізують інтерфейс PreviewWrapper, і використовувати їх як універсальний контейнер для будь‑якого прев’ю‑контенту.
Типовий сценарій, знайомий кожному Android‑розробнику на Compose: для кожного прев’ю доводиться вручну обгортати composable у тему застосунку. У результаті код прев’ю рясніє повторюваними блоками з викликом MyAppTheme { ... }, які дублюються десятки разів по всьому проєкту.
Preview wrappers змінюють цю модель. Тепер можна створити окремий theme‑wrapper, який приймає контент прев’ю й автоматично загортає його в потрібну тему. Далі цей wrapper підключається через анотацію — і всі прев’ю, що її використовують, автоматично отримують однакове тематичне оформлення.
Це дає кілька практичних переваг. По‑перше, зникає дублювання коду: тема визначається в одному місці, а не в кожному прев’ю окремо. По‑друге, забезпечується консистентність: складніше забути про тему в одному з прев’ю або випадково застосувати іншу. По‑третє, спрощується експериментування з дизайном: зміна теми в wrapper’і миттєво впливає на всі пов’язані прев’ю.
Можливості preview wrappers не обмежуються лише темами. Концепція обгортки дозволяє створювати спільні layout‑контейнери для прев’ю, додавати стандартні відступи, фонові кольори, debug‑рамки, імітацію різних розмірів екранів або станів системи. Фактично, це ще один рівень композиції, але орієнтований саме на дизайн‑час, а не на продакшн‑UI.
Для команд, які активно використовують прев’ю як інструмент дизайну й рев’ю інтерфейсів, це може суттєво зменшити фрикцію й зробити прев’ю більш системними, а не набором розрізнених прикладів.
Стилі проти модифікаторів: експериментальний styles API як спроба переосмислити декларацію вигляду
Ще один напрямок еволюції Compose — експериментальний styles API. Він не відкриває принципово нових можливостей, але пропонує інший спосіб опису візуальних атрибутів, які сьогодні традиційно задаються через Modifier.
Сьогодні майже будь‑яка декларація вигляду composable — це ланцюжок модифікаторів: фон, розмір, відступи, клік‑обробники, ефекти натискання, анімації. У складних компонентах такі ланцюжки можуть ставати важкочитабельними, а порядок модифікаторів — критичним для результату.
Styles API пропонує альтернативу: описувати стилі в більш декларативній формі, ближчій до DSL‑підходу. Простим атрибутам, на кшталт ширини, висоти чи фону, можна відповідати плоскими властивостями стилю. Для станів, наприклад натиснутого елемента, пропонується більш виразний синтаксис, типовий для Kotlin‑DSL, де стилі для різних станів описуються як частина єдиної декларації.
Ідея полягає в тому, щоб відокремити «що» від «як»: стилі описують, як має виглядати компонент у різних станах, а механіка застосування цих стилів може бути оптимізована під капотом. Згадується й потенційний бонус у вигляді продуктивності: централізоване керування стилями може дозволити оптимізувати перерахунок і застосування візуальних атрибутів.
Водночас styles API не позиціонується як негайна заміна модифікаторів. Швидше, це паралельний шлях, який може виявитися зручнішим для певних сценаріїв: складних дизайн‑систем, повторно використовуваних компонентів, де важливо явно фіксувати стилі для різних станів, а не розмазувати їх по ланцюжку модифікаторів у різних місцях.
Поки що це експеримент, і навіть серед досвідчених розробників реакція змішана. Частина ставить під сумнів необхідність ще одного способу опису вигляду, якщо вже існує потужний і гнучкий Modifier. Інші бачать у styles API шанс зробити декларацію UI більш структурованою й ближчою до того, як стилі описуються в інших екосистемах. Остаточну відповідь дасть практика: чи стане styles API масово використовуваним, чи залишиться нішевим інструментом для специфічних кейсів.
Grid: Compose наближається до CSS‑парадигми макетів
Найяскравіше оновлення в частині макетів — поява нового composable для побудови сіток, який за концепцією дуже нагадує CSS Grid. До цього моменту розробникам доводилося комбінувати LazyVerticalGrid, Row, Column та інші компоненти, щоб отримати складні сіткові інтерфейси. Тепер Compose отримує повноцінний Grid‑layout із можливістю керувати заповненням рядків і колонок окремими елементами.
Ключова відмінність нового Grid від простих «табличних» макетів у гнучкості. Це не просто фіксована сітка 4×4. Кожен елемент може займати кілька колонок або рядків, формуючи асиметричні, «журнальні» або дашбордні макети. Наприклад, одна плитка може розтягуватися на дві колонки й два рядки, тоді як сусідні займають по одній клітинці.
Особливо важливо, що Grid у Compose підтримує анімацію змін макета. Коли елементи змінюють розмір, порядок або область, яку займають, переходи між станами можуть бути плавно анімовані. Для інтерфейсів на кшталт інформаційних панелей, динамічних галерей, адаптивних домашніх екранів це відкриває можливість створювати складні, але візуально цілісні й приємні для користувача сценарії.
До появи Grid подібні інтерфейси вимагали або значної кількості кастомного layout‑коду, або компромісів у дизайні. Тепер Compose пропонує готовий примітив, який концептуально знайомий фронтенд‑розробникам, що працюють із CSS Grid, і водночас органічно вписується в декларативну модель Compose.
Це ще один крок до зближення світу Android‑UI з веб‑парадигмами. Для команд, які працюють над крос‑платформенними продуктами й мають сильну веб‑експертизу, це спрощує перенесення дизайн‑патернів і мислення в мобільний контекст.
Flexbox: курс на заміну FlowRow і FlowColumn знайомою веб‑моделлю
Паралельно з Grid у Compose з’являється ще один знайомий веб‑розробникам інструмент — Flexbox. Це експериментальний layout, API якого майже повністю віддзеркалює CSS Flexbox: із властивостями flexGrow, flexShrink, flexWrap, justifyContent, alignItems та іншими звичними термінами.
До цього моменту роль «гнучких» рядів і колонок у Compose виконували FlowRow і FlowColumn. Вони дозволяли елементам переноситися на наступний рядок або колонку, коли не вистачало місця, і надавали базові можливості вирівнювання. Однак їхня модель не була повною аналогією Flexbox, а термінологія відрізнялася від веб‑світу.
Новий Flexbox у Compose покликаний цю ситуацію змінити. Ідея полягає в тому, щоб зробити його основним рішенням для побудови гнучких, адаптивних рядів і колонок, а FlowRow і FlowColumn у перспективі відправити в розряд застарілих. Це не просто ще один layout, а спроба уніфікувати мову опису інтерфейсів між вебом і Android.
Для розробників, які вже знайомі з CSS Flexbox, вхідний поріг різко знижується: ті самі властивості, ті самі концепції розподілу простору, зростання й стискання елементів, перенесення рядків. Для «чистих» Android‑розробників це, навпаки, означає необхідність вивчити нову модель, але натомість вони отримують більш гнучкий і детально керований інструмент, ніж поточні Flow‑компоненти.
Flexbox у Compose залишається експериментальним, але вже має окрему документацію з описом сценаріїв використання та відмінностей від існуючих layout’ів. За своїми можливостями він ближчий до веб‑оригіналу, ніж до FlowRow/FlowColumn, і пропонує тонше керування вирівнюванням, розподілом простору й поведінкою елементів при зміні розміру контейнера.
Якщо цей підхід приживеться, Compose отримає більш послідовну й передбачувану модель побудови гнучких макетів, а перехід між веб‑та Android‑UI стане менш болючим як для дизайнерів, так і для розробників.
Висновки: Compose дорослішає й зближується з веб‑світом
Квітневий реліз Jetpack Compose демонструє одразу кілька важливих трендів. По‑перше, фреймворк стає більш «серйозним» щодо тестування: перехід на StandardTestDispatcher у UI‑тестах змушує команди усвідомлено працювати з асинхронністю й зменшує ризики прихованих помилок. Це болюча, але здорова еволюція.
По‑друге, інструменти розробки інтерфейсу стають зручнішими: preview wrappers знімають рутину з оформлення прев’ю й допомагають будувати більш системний дизайн‑процес, а експериментальний styles API відкриває дискусію про те, як саме має виглядати декларація стилів у Compose.
По‑третє, у частині макетів Compose робить явний крок у бік веб‑парадигм. Поява Grid і Flexbox із термінологією та можливостями, близькими до CSS, спрощує життя тим командам, які працюють на межі вебу й мобайлу, й дає Android‑розробникам доступ до перевірених роками моделей побудови складних, адаптивних інтерфейсів.
Разом ці зміни показують, що Jetpack Compose виходить за рамки просто «декларативного UI для Android» і поступово перетворюється на повноцінну платформу з власною екосистемою інструментів, але при цьому уважно придивляється до рішень, які вже давно працюють у веб‑світі.


