Compose Broadcast
Відкрити в Telegram
Все о Jetpack Compose и Compose Multiplatform По сотрудничеству - @ab_manager
Показати більше5 884
Підписники
-224 години
-127 днів
-930 днів
Завантажуємо дані
Схожі канали
Хмара тегів
Вхідні та вихідні згадування
---
---
---
---
---
---
Залучення підписників
жовтень '26жовт '26
жовтень '26
+41
в 0 каналах
вересень '26
+36
в 0 каналах
Get PRO
серпень '26
+44
в 2 каналах
Get PRO
липень '26
+35
в 2 каналах
Get PRO
червень '26
+48
в 2 каналах
Get PRO
травень '26
+74
в 0 каналах
Get PRO
квітень '26
+91
в 1 каналах
Get PRO
березень '26
+71
в 2 каналах
Get PRO
лютий '26
+51
в 1 каналах
Get PRO
січень '26
+47
в 0 каналах
Get PRO
грудень '25
+104
в 2 каналах
Get PRO
листопад '25
+62
в 0 каналах
Get PRO
жовтень '25
+298
в 3 каналах
Get PRO
вересень '25
+106
в 5 каналах
Get PRO
серпень '25
+76
в 1 каналах
Get PRO
липень '25
+54
в 1 каналах
Get PRO
червень '25
+53
в 1 каналах
Get PRO
травень '25
+162
в 7 каналах
Get PRO
квітень '25
+109
в 3 каналах
Get PRO
березень '25
+74
в 1 каналах
Get PRO
лютий '25
+110
в 2 каналах
Get PRO
січень '25
+81
в 0 каналах
Get PRO
грудень '24
+254
в 2 каналах
Get PRO
листопад '24
+116
в 2 каналах
Get PRO
жовтень '24
+255
в 2 каналах
Get PRO
вересень '24
+121
в 1 каналах
Get PRO
серпень '24
+199
в 1 каналах
Get PRO
липень '24
+108
в 1 каналах
Get PRO
червень '24
+153
в 1 каналах
Get PRO
травень '24
+269
в 4 каналах
Get PRO
квітень '24
+393
в 5 каналах
Get PRO
березень '24
+159
в 3 каналах
Get PRO
лютий '24
+197
в 3 каналах
Get PRO
січень '24
+220
в 2 каналах
Get PRO
грудень '23
+130
в 3 каналах
Get PRO
листопад '23
+116
в 4 каналах
Get PRO
жовтень '23
+379
в 3 каналах
Get PRO
вересень '23
+67
в 0 каналах
Get PRO
серпень '23
+2 598
в 0 каналах
| Дата | Залучення підписників | Згадування | Канали | |
| 26 жовтня | 0 | |||
| 25 жовтня | +2 | |||
| 24 жовтня | +1 | |||
| 23 жовтня | +2 | |||
| 22 жовтня | +1 | |||
| 21 жовтня | +1 | |||
| 20 жовтня | 0 | |||
| 19 жовтня | +4 | |||
| 18 жовтня | 0 | |||
| 17 жовтня | +2 | |||
| 16 жовтня | +1 | |||
| 15 жовтня | +3 | |||
| 14 жовтня | 0 | |||
| 13 жовтня | +2 | |||
| 12 жовтня | +6 | |||
| 11 жовтня | +2 | |||
| 10 жовтня | +2 | |||
| 09 жовтня | +2 | |||
| 08 жовтня | +1 | |||
| 07 жовтня | +1 | |||
| 06 жовтня | +4 | |||
| 05 жовтня | +1 | |||
| 04 жовтня | +1 | |||
| 03 жовтня | +1 | |||
| 02 жовтня | 0 | |||
| 01 жовтня | +1 |
Дописи каналу
CmpDevicePreview от Apadmi рисует приложение на Compose Multiplatform в рамке устройства. Рядом панель, в которой переключаются модель, ориентация, тёмная тема, размер текста, язык и клавиатура. Работает на Android, iOS, macOS, Desktop, JS и Wasm, поэтому веб-демо приложения можно выложить в интернет.
implementation("com.apadmi:cmpdevicepreview:0.1.0")
DeviceWithConfigurationView {
App()
}
Insets, isSystemInDarkTheme(), font scale и window size classes внутри рамки берутся от симулированного устройства, так что менять код приложения не нужно. В вебе настройки попадают в URL, и превью можно отправить ссылкой.
⚠️ На Android нельзя подменить insets и тёмную тему хоста, а диалоги выходят за рамку. Версия 0.1.0, API ещё меняется.🔗 GitHub · Live demo #Compose #ComposeMultiplatform #KMP #Kotlin
| 2 | ⚙️ ComposeStateMonitor: лог объясняет, почему composable перерисовался
Экран дёргается, Layout Inspector показывает растущий счётчик рекомпозиций, но не говорит главного: какой параметр или стейт её вызвал. ComposeStateMonitor отвечает как раз на этот вопрос. Вы вешаете на функцию @ComposableMonitor, плагин компилятора дописывает в неё отслеживание параметров и State-переменных, и при каждой рекомпозиции в лог падает строка:
CounterLabel recomposed because
`count` changed from `0` to `1`
Работает на всех таргетах Compose Multiplatform: Android, desktop, iOS, wasmJs и js. Нужны Kotlin 2.0+ (под каждую линию 2.0–2.4 своя сборка плагина), Gradle 7.6+ и Compose 1.6.11+. На Android по умолчанию инструментируется только debug, на остальных платформах мониторинг лучше включать Gradle-свойством. Идея и трекер изменений взяты из Rebugger, но здесь не нужно вручную перечислять, что отслеживать.
⚠️ Проект совсем свежий: репозиторий появился 22 октября, версия 0.2.0. Лямбды, локальные функции и стейт во вложенных блоках пока не отслеживаются.
🔗 GitHub
#Compose #CMP #KMP #Android | 1 608 |
| 3 | ⚙️ Прогрессивный blur в Compose: Google выпустил гайд по новым API из 1.13
До сих пор Modifier.blur умел одно: размыть композабл целиком с одинаковым радиусом. Чтобы края списка мягко уходили в размытие, приходилось писать свой шейдер или брать библиотеку вроде Haze. В Compose UI 1.13.0-beta01 появились BlurRadiusSpec и BlurStop, и теперь в документации есть гайд и готовые рецепты.
Радиус теперь меняется по поверхности: градиентом сверху вниз, слева направо, по линии или от точки. Например, так края списка размываются, а центр остаётся чётким:
LazyColumn(
modifier = Modifier.blur(
blurRadiusSpec = BlurRadiusSpec.verticalGradient(
stops = listOf(
BlurStop(fraction = 0f, radius = 18.dp),
BlurStop(fraction = 0.42f, radius = 0.dp),
BlurStop(fraction = 0.58f, radius = 0.dp),
BlurStop(fraction = 1f, radius = 18.dp),
),
),
edgeTreatment = BlurredEdgeTreatment.Unbounded,
),
) { /* ... */ }
⚠️ Modifier.blur размывает то, что рисует сам композабл. Размытие фона под панелью (backdrop blur) гайд не покрывает, а переменный радиус ограничен 150 px.
🔗 Гайд · Примеры
#Compose #JetpackCompose #Android | 2 112 |
| 4 | Немає тексту... | 2 002 |
| 5 | ⚙️ Дизайн-система как контракт: Konsist и Lint не дают обойти её в Compose
Дизайн-система есть почти у каждой команды, но через пару месяцев на одном экране отступ 16.dp, на другом 18.dp, где-то свой TextStyle и захардкоженный hex-цвет. Ревью всё не ловит. Ravi Rawal предлагает считать дизайн-систему инженерным контрактом и проверять его автоматически.
Konsist следит за архитектурой: фичи не должны зависеть от внутренностей дизайн-системы.
Konsist.scopeFromProject().assertArchitecture {
val features = Layer("Features", "com.acme.feature..")
val dsInternal = Layer("DS Internal", "com.acme.designsystem.internal..")
features.doesNotDependOn(dsInternal)
}
Но Color(0xFF1769E0) прямо в фиче такой тест пропустит. Здесь нужен свой Lint-детектор, а UI-тесты проверяют то, что видно только в рантайме.
⚠️ Детектор из статьи — стартовый: Color.Red или цвет из константы он не поймает.
🔗 Статья · Konsist
#Compose #JetpackCompose #Android #Konsist | 2 123 |
| 6 | 🐱 nav3-uikit: Navigation 3 в CMP с настоящим UINavigationController на iOS
Автор nav3-uikit предлагает простую сделку: переименуйте NavDisplay в NativeNavDisplay, и экраны Compose Multiplatform на iOS окажутся внутри настоящего UINavigationController. Кнопка «Назад», свайп от края и меню истории — уже не имитация, а сам UIKit.
NativeNavDisplay(
backStack = backStack,
onBack = { backStack.removeLastOrNull() },
entryProvider = entryProvider {
entry<Home>(metadata = NativeNavigation.title("Home", large = true)) { HomeScreen() }
},
)
Каждый экран — отдельный ComposeUIViewController, а через metadata можно включить large title или открыть экран как нативный sheet. Для вкладок есть NativeTabDisplay с UITabBarController. Источником правды остаётся ваш back stack: системный pop вызывает onBack, а если приложение его отклонит, экран вернётся на место. На Android и десктопе всё работает через обычный NavDisplay.
⚠️ Проект экспериментальный: версия 0.1.0-dev01, репозиторий создан 16 октября. Нативные вкладки требуют iOS 18+.
🔗 GitHub · Как это устроено
#Compose #CMP #Navigation3 #iOS | 2 088 |
| 7 | ⚙️ Spyglass: агент наконец видит Compose UI, который сам написал
Агент может написать экран на Compose, который компилируется, но не видит, что отступ съехал, текст обрезан, а кнопка не того цвета. Это выясняется, только когда вы откроете IDE. Spyglass закрывает этот пробел: рендерит @Preview в PNG без IDE, эмулятора и устройства и сравнивает результат с макетом.
В ответ агент получает процент совпадения, список отличающихся областей в px и dp и тепловую карту. Дальше он сам правит код и сравнивает снова. В демо так нашлась даже ошибка в одной букве: «Priority Support» вместо «Priority support».
Работает из командной строки, в CI и как MCP-сервер для Claude и других агентов. Билд-файлы трогать не надо: CLI запускает ваш gradlew со своим init-скриптом только на время рендера.
⚠️ Проект на ранней стадии (0.1.0, появился 15 октября): сейчас рендерятся превью из commonMain и desktop-кода Compose Multiplatform, Android-only превью пока только в планах.
🔗 GitHub · Релиз
#AI #MCP #Compose #KMP | 1 826 |
| 8 | ⚙️ Compose → PDF: счёт можно сверстать composable-функцией
В начале октября в kotlinlang #compose спросили: как на сервере отрендерить Compose UI в PDF, например для генерации счетов? На Android есть PDF API с Canvas, а на JVM? Через ImageComposeScene получится только картинка внутри PDF, без векторного текста. Skia умеет писать PDF сама, но в Skiko эта поддержка так и не появилась (SKIKO-1017). Автор вопроса в итоге остановился на готовой библиотеке compose2pdf.
compose2pdf работает на Compose Desktop: перехватывает отрисовку через SVGCanvas Skia и переводит её в PDF через PDFBox. Текст остаётся выделяемым, шрифты встраиваются, страницы разбиваются автоматически, а результат можно стримить прямо из Ktor.
val pdf = renderToPdf(config = PdfPageConfig.A4WithMargins) {
Text("Invoice #1234", fontSize = 24.sp, fontWeight = FontWeight.Bold)
Text("Amount: $1,250.00")
}
Если PDF нужен и в мобильном приложении, есть compose-multiplatform-pdf-export для Android, iOS и JVM: на Android он пишет через PdfDocument, на iOS — в PDF-контекст CoreGraphics.
⚠️ compose2pdf — только JVM, Android и iOS он не поддерживает. Обе библиотеки сторонние и появились в этом году.
🔗 Обсуждение · compose2pdf · compose-multiplatform-pdf-export
#Compose #CMP #KMP #PDF | 2 284 |
| 9 | 🐱 compose-desktop-native: Compose Desktop без JVM, одним нативным бинарником
Compose Desktop работает только на JVM, поэтому даже маленькая утилита едет к пользователю вместе с Java. Автор compose-desktop-native пошёл другим путём: собрал Compose на Kotlin/Native, а окна, ввод, звук, диалоги и буфер обмена отдал SDL3. На выходе получается один исполняемый файл для macOS, Linux или Windows, без JVM.
Compose при этом не переписан: runtime берётся официальный, а ui, foundation и material3 скопированы из Compose Multiplatform как есть. Рисует всё тот же Skia.
fun main() = nativeComposeWindow(title = "Hello") {
Text("Hello from Compose Desktop Native")
}
В свой проект его подключают Gradle-плагином: вы объявляете обычные зависимости Compose, а плагин подменяет их на порт только для нативных desktop-таргетов. Android, JVM, iOS и Web продолжают собираться на официальных артефактах.
⚠️ Это сторонний проект, а не JetBrains: артефакты — форк com.bitsycore, на Windows используется форк Skiko. Репозиторию четыре месяца.
🔗 GitHub · Пример с плагином
#Compose #CMP #KotlinNative #Desktop | 2 288 |
| 10 | ⚙️ Свой rich text редактор на TextField: Google выпустил подробный гайд
В августе Compose Foundation 1.12 научил TextFieldState хранить SpanStyle и ParagraphStyle вместе с текстом. Но как сделать кнопку «жирный», которая работает с выделением и не ломается при правках, приходилось разбираться самим. Теперь в документации есть отдельный гайд, а полная реализация лежит в сэмпле Jetchat.
Ключевая настройка — ExpandPolicy: она решает, подхватит ли стиль текст, напечатанный ровно на его границе. AtEnd ведёт себя как обычный редактор, InsideOnly подходит для @упоминаний, которые не должны «расползаться».
state.edit {
addStyle(
spanStyle = SpanStyle(fontWeight = FontWeight.Bold),
range = selection,
expandPolicy = ExpandPolicy.AtEnd
)
}
addStyle возвращает TrackedRange, который сам сдвигается при правках и живёт только внутри edit. Для тулбара и сериализации есть TextFieldState.textStyles.
🔗 Гайд · Jetchat
#Compose #JetpackCompose #Android | 2 242 |
| 11 | 🧭 Навигация из Android-приложения переезжает в общий код Compose Multiplatform
В JetBrains напомнили Android-разработчикам: знакомые NavController и NavHost можно вынести в общий код и получить одну модель навигации с типобезопасными маршрутами, одним графом и одним стеком экранов на Android, iOS, десктопе и в вебе. Всё это собрано в разделе документации Kotlin Multiplatform «Navigation in Compose».
Мультиплатформенную поддержку в библиотеку AndroidX Navigation добавляет команда Compose Multiplatform, поэтому подход тот же, что на Android: маршрут — сериализуемый объект или data class с аргументами, а граф описывается внутри NavHost:
@Serializable
object Profile
@Serializable
object FriendsList
val navController = rememberNavController()
NavHost(navController = navController, startDestination = Profile) {
composable<Profile> { ProfileScreen( /* ... */ ) }
composable<FriendsList> { FriendsListScreen( /* ... */ ) }
}
Подключается всё одной зависимостью org.jetbrains.androidx.navigation:navigation-compose в commonMain. Жест «назад» библиотека переводит в возврат на предыдущий экран на каждой платформе: на iOS это свайп, на десктопе — клавиша Esc. Для iOS по умолчанию включена анимация перехода в духе нативной, но если задать свои enterTransition или exitTransition, она отключится. Выключить обработку жеста на iOS можно флагом enableBackGesture = false в ComposeUIViewController.
⚠️ Диплинки по умолчанию не видны внешним приложениям: URI-схему нужно отдельно зарегистрировать в каждой целевой ОС. А если на iOS нужны системные эффекты вроде Liquid Glass в навигационном интерфейсе, документация советует перенести навигацию в нативный SwiftUI и оставить Compose для содержимого экранов.
🔗 Navigation in Compose · пост Kotlin
#Compose #ComposeMultiplatform #Kotlin #Navigation | 2 524 |
| 12 | 🧭 В рецептах Navigation 3 для модульного приложения появились диплинки
Google переписал гайды Modular with Hilt и Modular with Koin: каждый feature-модуль теперь регистрирует не только свои экраны, но и сопоставитель (matcher) для диплинка. Вот как это делает модуль профиля в варианте с Hilt:
@IntoSet
@Provides
fun provideDeepLinkMatcher(): BackStackMatcher<*, NavKey> =
UriDeepLinkMatcher(
uriPattern = DeepLinkUri(PROFILE_URI),
serializer = Profile.serializer(),
).withBackStack { matchResult ->
listOf(ConversationList, matchResult.key)
}
Navigator.handleDeepLink(intent) в модуле common перебирает все такие сопоставители и по URI собирает искусственный стек экранов, а для обычного запуска и запуска по диплинку в примерах заведены отдельные Activity. Так фичу можно открыть по ссылке, не зная, как устроена навигация в соседних модулях.
🔗 Hilt · Koin
#Compose #Navigation3 #AndroidDev | 3 825 |
| 13 | ⚙️ Вышел Compose Multiplatform 1.12.2
Патч к 1.12.1 без новых фич — три точечных фикса. Gradle-плагин и библиотеки: org.jetbrains.compose:1.12.2.
👉 Multiple platforms: убрали мигание при анимации непрямоугольных graphicsLayer-теней (#3465)
👉 iOS: краш, когда TextField терял фокус из‑за показанного Dialog (#3459)
👉 Web: поведение фокуса backing text input под iOS Safari 27.0 (#3466)
Material3 в этом релизе по‑прежнему на 1.12.0-alpha03, Navigation3 — 1.2.0-rc01. Имеет смысл обновиться, если ловили эти баги.
🔗 Release notes 1.12.2
#Compose #CMP #KMP | 4 040 |
| 14 | ⚙️ Compose Foundation 1.13: TextField с value/onValueChange уходит в deprecated
В 1.13.0-alpha03 (сейчас уже beta01) BasicTextField(value, onValueChange) и такие же перегрузки Material 2 TextField помечены deprecated. Замена — state-based API на TextFieldState.
👉 Маски: VisualTransformation тоже deprecated, переходите на OutputTransformation. Пишете insert(4, "-"), а offset mapping считается автоматически
👉 Фильтрация переезжает из onValueChange в InputTransformation. maxLength deprecated: вместо него maxLengthTrim (обрезает) и maxLengthReject (отклоняет ввод)
👉 ViewModel: держать TextFieldState во ViewModel нормально, но отдельно от UiState
👉 Кому и когда: всем, у кого есть формы. Пока это только предупреждения компилятора, код собирается. Мигрировать лучше заранее, особенно маски и StateFlow-формы
// было
TextField(value = text, onValueChange = { text = it })
// стало
TextField(state = rememberTextFieldState())
🔗 Гайд по миграции
🔗 Release notes
#Compose #JetpackCompose #Android | 4 146 |
| 15 | ИИ помогает писать код для Android — но как проверить, что он действительно работает? 🚀
21 октября в 20:00 МСК — открытый вебинар "Написание текстов для Android в эпоху ИИ"
👨🏻💻 На вебинаре курса «Android-разработчик. Продвинутый уровень»:
• разберём пирамиду тестирования и соотношение уровней проверок;
• пройдёмся по модульным и интеграционным тестам, тестам интерфейса, проверкам по снимкам экрана и архитектурным тестам;
• для каждого вида обсудим пользу для проекта и случаи, когда его стоит применять;
• отдельно — почему эти проверки нужны при работе с ИИ и как выбирать тесты для Android-приложения.
🧩 После урока вы:
— увидите тестирование как систему, а не набор разрозненных практик;
— поймёте назначение разных видов проверок;
— сможете выбирать подходящие тесты под свою задачу;
— начнёте системнее проверять код в своих проектах.
Спикер: Максим Качинкин.
👉 Регистрация на открытый вебинар: тут
Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576 | 2 070 |
| 16 | ⚙️ Скилл по аудиту производительности Compose опубликовали. Доступен через Android CLI
#Compose #AndroidDev #AI | 3 063 |
| 17 | ⚙️ Скилл по аудиту производительности Compose опубликовали. Доступен через Android CLI
#Compose #AndroidDev #AI | 2 |
| 18 | Mobile вызывает. Ответите? 📱
VK JT Mobile Meetup на связи сразу в двух городах:
📍 В Москве — 31 октября
📍 В Санкт-Петербурге — 14 ноября
В Москве вас ждут два параллельных трека — iOS и Android, а в Петербурге — один общий мобайл-трек.
На проводе будут инженеры ВКонтакте, Дзена, MAX, VK Tech и других команд ВК. В программе — реальные кейсы мобильной разработки: 120 FPS, анализ влияния, сравнительные тесты, ИИ, архитектура и другие задачи производства.
После докладов можно обсудить кейсы с другими разработчиками, поучаствовать в интерактивах и пообщаться на вечеринке.
Мероприятие рассчитано на iOS- и Android-разработчиков и пройдут только офлайн. Принимайте вызов в своём городе!
→ Регистрация
#реклама | 3 621 |
| 19 | ⚙️ Google переписал гайд по стабильности в Compose: часть старых советов теперь наоборот
Старая версия писала, что нестабильный параметр значит рекомпозицию всегда. Но с Kotlin 2.0.20 по умолчанию работает Strong Skipping, и нестабильные параметры сравниваются по ссылке (===). Гайд наконец под это обновили, и советы поменялись.
👉 Коллекции. Раньше советовали Kotlinx immutable collections или @Immutable/@Stable. Теперь: не делайте этого без нужды в equals(). === стоит O(1), а equals() по большому списку на каждой рекомпозиции может выйти дороже самой рекомпозиции
👉 Типы из других модулей. Вместо обёрток в UI-модели теперь файл конфигурации стабильности или аннотации, но только для небольших моделей с дешёвым equals()
👉 Отладка. Первым делом проверьте, не создаётся ли новый экземпляр нестабильного параметра на каждой рекомпозиции
🔗 Stability in Compose
#Compose #AndroidDev #Performance | 3 558 |
| 20 | ⚙️ Google выпустил официальный скилл для аудита производительности Compose
Агенты любят лечить тормоза в Compose через @Stable, @Immutable и ImmutableList. Новый скилл Google прямо это запрещает для моделей с коллекциями: со Strong skipping (по умолчанию с Kotlin 2.0.20) .equals() по списку дороже, чем сравнение по ===.
Агент проверяет код по 7 категориям и перед каждой правкой читает справочный гайд:
👉 state и stability: чтение state в Layout/Draw, backwards writes, computedStateOf в Compose 1.13+
👉 лейауты: без onGloballyPositioned и BoxWithConstraints в горячих местах
👉 Lazy: key и contentType, без LaunchedEffect для аналитики в items
👉 анимации, эффекты и Flow, графика (drawWithCache), миграция на Modifier.Node
Сначала скилл требует release-сборку, R8 и Baseline Profiles.
Ставится через Android CLI: ищите в android skills list и добавляйте через android skills add. Про остальные скиллы Google писал тут.
🔗 Скилл
#Compose #AI #Performance | 3 538 |
