Compose Broadcast
5.9K subscribers
375 photos
95 videos
619 links
Все о Jetpack Compose и Compose Multiplatform

По сотрудничеству - @ab_manager
Download Telegram
⚙️ Вышел Compose Multiplatform 1.9.2 с исправление багов и обновление на свежие артефакты из Jetpack: Compose 1.9.4, Lifecycle 2.9.4, SavedState 1.3.3, WindowManager 1.4.0 и Material3 1.4.0

#compose #kmp #cmp
Please open Telegram to view this post
VIEW IN TELEGRAM
⚙️ Compose Stability Analyzer включает в себя плагин компилятора, который в рантайме позволяет в логах видеть информацию по рекомпозиции функций. Работает с Kotlin Multiplatform

@TraceRecomposition
fun MyComposable(...) { ... }


#compose #производительность #kmp #cmp
⚙️ KMP Wheel Picker - крутелка c выбором в iOS стиле на Compose

// Пример использования
WheelPicker(
state = state,
bufferSize = 3,
window = { ... },
) { index ->
Text(
"Item ${index + 1}",
Modifier.padding(16.dp, 8.dp),
)
}


#compose #cmp #ios
Please open Telegram to view this post
VIEW IN TELEGRAM
🐱 Heron - open source клиент для соц сети Bluesky. Приложения на Jetpack Compose Multiplatform для Android, iOS и Desktop

Тех стек:
👉 Многомодульная архитектура
👉 Metro DI
👉 Coil для показа картинок
👉 Kotlin Coroutines и SerlializationX
👉 Ktor
👉 Jetpack Room

#compose #cmp #kmp #android #ios #desktop #пример #opensource
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
⚙️ Вышел Compose Multiplatform 1.10.0 Beta 1

Что нового:
🔨 @Preview аннотация работает в Common коде
🚀 Поддержка Jetpack Navigation 3

Compose iOS
❗️ Поддержка WIndowsInsetsRulers - API дял расположения элементов относительно системного UI
👉 Прокачали работу с софт клавиатурой

Compose Desktop:
👉 Compose Hot Reload теперь теперь часть Compose. Больше не нужна отдельная зависимость
👉 SwingPanel теперь автоматически подстраивает свой размер на основе размеров контента в ней

Gradle плагин:
👉 Алиасы для Compose зависимостей в Gradle теперь не рекомендуютя к использованию. Подключаем артефакты как и все другие
👉 Поддержка Android Gradle Plugin 9.0.0

#compose #cmp #gradle #ios #desktop
Please open Telegram to view this post
VIEW IN TELEGRAM
⚙️ Пререндеринг UI в Lazy списках Compose

В Compose есть возможность настраивать размер кэша для lazy layouts! Можно контролировать, сколько элементов сохранять до и после видимой области.

Что изменилось?
👉 До версии 1.9: Lazy списки компилировали только 1 элемент вперед и сразу удаляли невидимые
👉 С версии 1.9: Можно задать точное количество сохраняемых элементов в dp или % viewport

Зачем это нужно?
Увеличивает плавность прокрутки за счет подготовки контента заранее
Оптимизирует использование pausable composition между кадрами
Позволяет балансировать между памятью и производительностью

Как использовать:
// Кэш в dp
val dpCacheWindow = LazyLayoutCacheWindow(
ahead = 150.dp, // 150dp вперед
behind = 100.dp // 100dp назад
)

// Или в процентах от viewport
val percentCacheWindow = LazyLayoutCacheWindow(
ahead = 0.5f, // 50% viewport вперед
behind = 0.3f // 30% viewport назад
)

val state = rememberLazyListState(cacheWindow = dpCacheWindow)

LazyColumn(state = state) {
// ваш контент
}


Рекомендации:
🎯 Начинайте с 50% viewport и тестируйте производительность
🎯 Для тяжелых элементов используйте больший кэш
🎯 Для легких списков можно уменьшить значения

Особенно полезно для сложных списков с изображениями, анимациями или тяжелой бизнес-логикой!

#Compose #Производительность #cmp
Please open Telegram to view this post
VIEW IN TELEGRAM
⚙️ Navigation 3 в Compose Multiplatform: новый подход от Google

Google представила Navigation 3 — совершенно новую библиотеку для навигации в Compose, где управление стеком экранов сводится к простым операциям с списком.

Хорошая новость: JetBrains уже адаптировали её для Compose Multiplatform! В статье на реальном примере показывает, как:
👉 Добавить зависимости Navigation 3 в KMP-проект
👉 Определить маршруты через sealed-интерфейсы с @Serializable
👉 Работать с back stack как с обычным mutable list
👉 Создать адаптивные layouts для разных размеров экранов

Особенно полезно будет:
✔️ Разработчикам, которые хотят использовать современный подход Google к навигации в кроссплатформенных проектах
✔️ Тем, кто ищет альтернативу существующим решениям вроде Voyager

В статье — чистый код из commonMain с примерами навигации между экранами и реализацией bottom navigation.

#compose #cmp #kmp
Please open Telegram to view this post
VIEW IN TELEGRAM
⚙️ Вышла вторая Beta Compose Multiplatform, где самое важное для меня - обновление на свежие версии зависимостей из Android Jetpack

#compose #cmp #kmp #androidjetpack
Please open Telegram to view this post
VIEW IN TELEGRAM
🐱 Daily Agenda View - Compose компонент для показа плана на день

#compose #cmp
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
⚙️ Navigation3 Browser — навигация для Web на основе Jetpack Navigation 3

Появилась реализация навигации под Web-браузер, совместимая с Jetpack Navigation 3 и интегрированная с нативной историей браузера. Автор — Костя Цховребов из JetBrains (KMP-команда).

Теперь Web-приложения на Compose Multiplatform могут работать с привычным поведением браузера: кнопки Back/Forward, корректное управление историей, восстановление состояния и предсказуемая работа нескольких экранов.

Поддерживаются две стратегии навигации:
👉 Chronological - Классическая браузерная модель: линейный переход по посещённым состояниям (Back/Forward).
👉 Hierarchical - Мобильная модель навигации, имитирующая структуру экранов и вложенную иерархию — аналогично Android-приложениям.

🧪 Обе стратегии можно сравнить в онлайн-демо

Пример использования Chronological-навигации

@Composable
fun App() {
val backStack = remember { mutableStateListOf<Any>(Root) }

ChronologicalBrowserNavigation(
backStack = backStack,
saveKey = { key ->
when (key) {
is Root -> buildBrowserHistoryFragment("root")
is Profile -> buildBrowserHistoryFragment(
"profile",
mapOf("id" to key.id.toString())
)
else -> null
}
},
restoreKey = { fragment ->
when (getBrowserHistoryFragmentName(fragment)) {
"root" -> Root
"profile" -> Profile(
getBrowserHistoryFragmentParameters(fragment)
.getValue("id")
?.toInt() ?: error("id is required")
)
else -> null
}
}
)

NavDisplay(backStack) { /* ... */ }
}


Navigation3 Browser кажется важным шагом для формирования единой модели навигации в Compose Multiplatform: Android → Desktop → Web.
Это упростит мультиплатформенную архитектуру и сделает перенос логики между платформами гораздо чище.

#Kotlin #Compose #KMP #CMP #WEB #AndroidJetpack #Jetpack
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥 Compose Hot Reload 1.0.0 — стабильный релиз!

JetBrains выпустили стабильную версию Compose Hot Reload, и это действительно круто!

Теперь когда меняете код Compose UI → жмете Cmd+S/Ctrl+S → изменения мгновенно применяются в запущенном приложении. Без перезапуска. Без потери state.

Можно добавлять/удалять функции, классы, параметры — практически любые изменения кода работают.

Стабильная версия 1.0.0 — больше не beta
Отдельный плагин НЕ нужен — встроен в Compose Multiplatform 1.10+, работает из коробки (zero configuration)
⚠️ Работает только на JVM Desktop — и вот почему это важно понять:

Почему только JVM Desktop?
Hot Reload требует JetBrains Runtime с DCEVM (Dynamic Code Evolution VM). Обычная JVM умеет перезагружать только тела методов. DCEVM может делать произвольные изменения кода — добавлять поля в классы, менять иерархию, интерфейсы и т.д.
Android и iOS не могут использовать JetBrains Runtime с DCEVM. Поэтому Hot Reload технически невозможен на этих платформах.

💡 Зачем это мобильным разработчикам?
Еще один повод добавить Desktop таргет в ваш KMP проект!

Даже если вы не планируете запускать Desktop версию в прод - это мощный инструмент для разработки:
👉 Быстро итерируете UI на Desktop с Hot Reload
👉 Проверяете изменения
👉 Переносите на Android/iOS

Скорость итераций UI вырастает в разы. Вместо "изменил → собрал → запустил → дождался" получается "изменил → Cmd+S → увидел результат".

Короче: если делаете Compose Multiplatform — попробуйте обязательно. Desktop таргет окупится только ради Hot Reload.

🔗 Подробности в блоге JetBrains и в документации

#Compose #KMP #Desktop #JVM #CMP
⚙️ Новинка Compose 1.11: неленивый Grid

До сих пор для сеток у нас были только ленивые LazyVerticalGrid / LazyHorizontalGrid. Но если все элементы уже в памяти (небольшое количество) и нужен точный контроль над расположением ячеек — пригождается новый экспериментальный Grid.

// Пример
Grid(config = {
column(100.dp)
column(1.fr) // забирает остаток строки
row(50.dp)
row(80.dp)
gap(8.dp)
}) {
Box(Modifier.gridItem().fillMaxSize()) { ... }
Box(Modifier.gridItem().fillMaxSize()) { ... }
Box(Modifier.gridItem().fillMaxSize()) { ... }
Box(Modifier.gridItem().fillMaxSize()) { ... }
}


Работает на Android и KMP (iOS, Desktop, Web) – общий API

🔗 Документация по Grid

#Compose #KMP #Android #iOS #Desktop #Web #CMP
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
This media is not supported in your browser
VIEW IN TELEGRAM
⚙️ FlexBox Layout в Jetpack Compose 1.11.0 - построение динамической сетки из компонентов

В составе androidx.compose.foundation:layout 1.11.0 появился компонент FlexBox. Компоновка на основе правил CSS Flexbox. Поддерживает перенос элементов (wrap), веса (weight), выравнивание по главной и поперечной осям. Сразу вышел с поддержкой Compose Multiplatform.

FlexBox(
modifier =
Modifier.fillMaxWidth(),
config = {
flexDirection = Row
flexWrap = Wrap
justifyContent = SpaceBetween
}
) {
repeat(items.size) { index ->
Text(
text = items[index],
modifier =
Modifier.weight(1f)
)
}
}


🔗 Анонс в блоге Android Developers
🔗 API Reference

#Compose #CMP
Please open Telegram to view this post
VIEW IN TELEGRAM
⚙️ Compose 1.11: Composition host defaults — мелочь, важная для KMP

В апрельском релизе Jetpack Compose под номером 1.11 в compose-runtime завезли четыре новых API: HostDefaultProvider, LocalHostDefaultProvider, HostDefaultKey и ViewTreeHostDefaultKey. Плюс билдер compositionLocalWithHostDefaultOf для авторов библиотек.

Он позволяют объявить CompositionLocal, у которого дефолтное значение резолвится из окружения хоста — например, через Android View tag'и (как это делает ViewTreeLifecycleOwner или ViewTreeOnBackPressedDispatcherOwner). Раньше для такого паттерна была обязательна зависимость на compose-ui. Теперь только compose-runtime.

Раньше чтобы из библиотеки достать значение из View tree, приходилось тянуть compose-ui ради LocalView и платформенные функции поиска по дереву View. Код жил в Android-сорсах, в commonMain такое не положишь:
    // androidMain — compose-ui + Android-only API
val LocalMyOwner = compositionLocalOf<MyOwner?> { null }

@Composable
fun ProvideMyOwner(content: @Composable () -> Unit) {
val view = LocalView.current
val owner = remember(view) {
view.findViewTreeMyOwner()
}
CompositionLocalProvider(LocalMyOwner provides owner) {
content()
}
}


С новым API описание CompositionLocal живёт в commonMain и тянет только compose-runtime. Связку с View tree описывает ViewTreeHostDefaultKey, и хост сам отдаёт значение через своего провайдера:

    // commonMain — только compose-runtime
val MyOwnerKey = ViewTreeHostDefaultKey<MyOwner>(
viewTagId = R.id.view_tree_my_owner
)

val LocalMyOwner = compositionLocalWithHostDefaultOf(MyOwnerKey)

// Использование — без изменений
@Composable
fun MyComponent() {
val owner = LocalMyOwner.current
// ...
}


Теперь авторы Compose библиотек могут держать определение CompositionLocal в общем модуле без зависимости на compose-ui. Профит - меньше транзитивных зависимостей в KMP-библиотеках и более чистое разделение слоёв runtime и UI.

#Compose #CMP
Please open Telegram to view this post
VIEW IN TELEGRAM
⚙️ Compose Multiplatform 1.11.0 вышел

Главные фичи:
1️⃣ Нативный text input на iOS через UIView, UITextInput и UIKeyInput (экспериментально)
2️⃣ v2 API для Compose UI-тестов на не-Android таргетах
3️⃣ Переписанный с нуля скроллинг на Web

Breaking изменения, которые заденут почти всех:
👉 Минималка Kotlin поднята до 2.3.10
👉 Минимальная iOS теперь 14 (поддержка 13 ушла)
👉 iosX64 и macosX64 удалены полностью
👉 Shader на не-Android стал wrapper-классом

Я ждал нативный input на iOS с того момента, как Compose туда заехал. Текущая реализация на Skia всегда чувствовалась чужой на ощупь, особенно при сложном выделении и системных меню. Надо пробовать!

#compose #cmp #kotlin
Please open Telegram to view this post
VIEW IN TELEGRAM
⚙️ MCP сервер в для Compose Desktop: агент сам видит UI и кликает

В Compose Multiplatform 1.12.0-rc01 (через Compose Hot Reload 1.2.0) появился экспериментальный MCP-сервер для Hot Reload.

Агент теперь может:
👉 reload — пересобрать и хотрелоудить
👉 take_screenshot — снять текущее окно
👉 get_semantic_tree — получить semantic tree (включая Dialog/Popup)
👉 click / type_text / scroll — симулировать ввод
👉 get_logs — читать runtime-логи и ошибки

Подключается через Gradle-таску. В конфиге агента (.mcp.json):

{
"mcpServers": {
"compose-hot-reload": {
"command": "./gradlew",
"args": [
"--no-daemon",
"--quiet",
"--console=plain",
"hotMcpServer"
]
}
}
}


#Compose #CMP #Desktop #HotReload
Please open Telegram to view this post
VIEW IN TELEGRAM
🐱 Адаптивный UI в Compose Multiplatform через набор простый функций

KitFlow — небольшая KMP-либа, которая показывает, как можно держать адаптив в одном месте.

Главная идея — Adaptive.value():
val padding = Adaptive.value(
sm = 12.dp,
md = 16.dp,
lg = 20.dp,
tab = 24.dp,
desktop = 28.dp
)


То же самое для высоты кнопки, ширины карточки, scale шрифта, Boolean, цветов, любых кастомных значений. Есть Adaptive.layoutValue() (по текущей ширине, включая split-screen и resize) и Adaptive.onOrientationChange для портрета/ландшафта.

Подключать как зависимость я не рекомендую. Всё, что там есть, легко реализовать самому, и тогда получаешь полную гибкость под свой дизайн-систем и breakpoints. А вот разобрать реализацию и вдохновиться будет полезно, особенно если пишешь shared UI под Android + iOS + Desktop + Web. Я еще для себя делал расширение в зависимости от таргет платформы.

#Compose #CMP #Adaptive #UI
Please open Telegram to view this post
VIEW IN TELEGRAM
⚙️ Compose Multiplatform 1.12.0: AI агент наконец видит, что написал

Вышел стабильный CMP 1.12.0.

Главное в релизе - MCP в Compose Desktop Hot Reload 1.2.0. Раньше агент правил @Composable вслепую: не знал, прошёл ли reload, что на экране, не упало ли. Теперь есть сервер с нормальными тулами. Поднимается таской, в .mcp.json достаточно hotMcpServer:

{
"mcpServers": {
"compose-hot-reload": {
"command": "./gradlew",
"args": ["--no-daemon", "--quiet", "--console=plain", "hotMcpServer"]
}
}
}


Много фиксов и улучшений для Desktop, Web, iOS. Еще отдельно расскажу постами в @compose_broadcast

🔗 Полный список изменений

#Compose #CMP #Desktop #AI
Please open Telegram to view this post
VIEW IN TELEGRAM
⚙️ Compose Web можно выложить как офлайн-приложение

В Issue CMP-10781 в официальном баг-трекере CMP Константин Цховребов расписал рецепт офлайн-приложения Compose Web: после Gradle-задачи wasmJsBrowserDistribution отдельная задача (исходный код в issue) копирует статику, вычисляет SHA-256 по путям и содержимому и генерирует service-worker.js.

Что получается на практике:
👉 index.html, JS, Wasm и Compose Resources кладутся в Cache Storage
👉 SW перехватывает только эти файлы
👉 запросы к API идут в сеть как обычно
👉 новая сборка меняет версию кэша и удаляет старый

Ограничения:
👉 cache.addAll() падает, если не скачался хотя бы один файл из списка
👉 source maps тоже попадают в кэш, если не отфильтровать
👉 новая версия подхватится только при следующем запуске

Это не официальная задача в плагине CMP и не «PWA из коробки», а лишь рецепт, который вполне может стать частью официального плагина в будущем.

#Compose #CMP #Wasm
Please open Telegram to view this post
VIEW IN TELEGRAM
This media is not supported in your browser
VIEW IN TELEGRAM
⚙️ Вышел Compose HotSwan 2.0.0 - Hot Reload для Android, iOS и Desktop. В новой версии прокачали движок определения изменений.

Полезно как для людей, так и для разработки с AI агентами, так как не приходится прокликивать приложение до экрана при каждых изменениях, что экономит токены.

💰Решение платное - 5$/месяц, есть триал на 2 недели.

💬 Если кто уже пробовал - делитесь опытом в комментариях

#Compose #CMP #Android #Desktop #iOS
Please open Telegram to view this post
VIEW IN TELEGRAM