Compose Broadcast
5.92K subscribers
371 photos
95 videos
610 links
Все о Jetpack Compose и Compose Multiplatform

По сотрудничеству - @ab_manager
Download Telegram
⚙️ Вышла стабильная версия Jetpack Compose 1.12.0! CMP уже подходе

Для обновления просто обновите BOM
implementation(platform("androidx.compose:compose-bom:2026.08.00"))


⚠️ Важно: требуется compileSdk = 37 и AGP 9.2.0+.

В этом релизе:
🎨 Mesh‑градиенты и HDR
📐 Именованные области в Grid
✍️ Редактируемое форматирование текста
🎬 Двухстадийные анимации
⚡️ Ускоренный старт и Keyed SideEffect
🔧 Не обошлось без breaking changes

В ближайших постах разберу каждую фичу подробно с примерами. Подпишись на @ComposeBroadcast, чтобы ничего не пропустить!

Compose Multiplatform 1.12.0 уже на стадии RC

#Compose #Android
Please open Telegram to view this post
VIEW IN TELEGRAM
👍25👎4
Please open Telegram to view this post
VIEW IN TELEGRAM
👍24👎5
⚙️ Compose Grid стал удобнее

Теперь области можно задавать через имя в Grid в дополнение к индексу. Дайте областям имена и размещайте элементы с помощью gridItem(areaId = "header"):
Grid(
config = {
area("header", row = 0, column = 0, rowSpan = 1, columnSpan = 2)
area("sidebar", row = 1, column = 0)
area("content", row = 1, column = 1)
}
) {
HeaderSection(modifier = Modifier.gridItem(areaId = "header"))
Sidebar(modifier = Modifier.gridItem(areaId = "sidebar"))
Content(modifier = Modifier.gridItem(areaId = "content"))
}

#Compose
Please open Telegram to view this post
VIEW IN TELEGRAM
👍29👎2
🚀 В Compose 1.12.0 прокачали производительность и по бенчмарку Google, на котором тестируются все версии, уже сравнялись с View.

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

#Compose #Performance
Please open Telegram to view this post
VIEW IN TELEGRAM
👍46👎3
⚙️ Улучшения текстовых полей в Compose 1.12.0

👉 В BasicTextField можно теперь программно применять SpanStyle и ParagraphStyle через edit { addStyle(...) }:
state.edit {
addStyle(SpanStyle(fontWeight = FontWeight.Bold), start = 0, end = 9)
}

Стили сохраняются при смене конфигурации.

👉 Программное управление выделением. Новый SelectionState с методами selectAll()clear(),  select(range) и extendSelectionByWord()
val selectionState = rememberSelectionState()
val characterCount = selectionState.selectedTexts.sumOf { it.text.length }

Column {
SelectionContainer(state = selectionState) {
Column { BasicText(text = "Text to be selected...") }
}
if (characterCount > 0) {
BasicText(text = "Characters selected: $characterCount")
}
}


👉 Текстовые поля теперь нативно поддерживают Android Credential Manager (API 34+) через семантическое свойство credentialRequest. Passkeys, сохранённые учётные данные — прямо из поля ввода.

👉 Новые KeyboardTypeDateTimeDateTimeSignedDecimal.

👉  BasicSecureTextField теперь по умолчанию использует TextObfuscationMode.System

#Compose
Please open Telegram to view this post
VIEW IN TELEGRAM
👍37👎2
Please open Telegram to view this post
VIEW IN TELEGRAM
👍20👎2
⚙️ В Compose 1.12.0 появилась экспериментальная реализация Slot Table на основе связного списка (LinkBuffer).

Slot Table — это внутренняя структура данных, в которой Compose Runtime хранит всё дерево композиции: каждый Composable, каждое состояние remember, ключи и связи между элементами. С момента первого релиза Slot Table был реализован на основе Gap Buffer — структуры, вдохновлённой текстовыми редакторами.

Gap Buffer хранит все группы в плоском IntArray с пустой областью (gap), которая перемещается к месту следующей записи. Его проблема что при удалении или переупорядочивании элементов gap должен переместиться к нужной позиции, копируя все элементы на своём пути.

Для композиции с 1000 группами удаление группы №500 требует перемещения gap через 500 позиций. Переупорядочивание одного элемента в списке из 100 записей требует двух перемещений gap, каждое с копированием части массива. По итогу чем больше композиция, тем дороже структурные изменения.

Новая экспериментальная реализация Slot Table на основе связного списка — LinkBuffer. Вместо плоского массива группы хранятся в виде связного списка с явными указателями на родителя, первого потомка и следующего соседа. Ключевое преимущество - структурные операции (удаление, перемещение, переупорядочивание) теперь требуют обновления указателей вместо копирования массивов.

По тестам разработчиков переупорядочивание списков стало более чем в 2 раза быстрее. Большинство других операций стали примерно на 10% быстрее

Флаг новой реализации отключён по умолчанию. Включить можно двумя способами:
1. Программно (только для debug-сборок):
// ДО вызова setContent()
ComposeRuntimeFlags.isLinkBufferComposerEnabled = true

2. Через R8/ProGuard (для release-сборок):
-assumevalues public class androidx.compose.runtime.ComposeRuntimeFlags {
static boolean isLinkBufferComposerEnabled return true;
}

В R8 release-сборках правило ProGuard всегда имеет приоритет над программной установкой.

#Compose #UnderHood
Please open Telegram to view this post
VIEW IN TELEGRAM
👍31👎3
⚙️ Новый релиз Material3 Adaptive 1.3.0

Новая библиотека adaptive-navigation3. Теперь можно легко строить адаптивные Material-интерфейсы в связке с Navigation 3. Что внутри:

Scene Strategies
👉 ListDetailSceneStrategy + rememberListDetailSceneStrategy — канонический list-detail
👉 SupportingPaneSceneStrategy + rememberSupportingPaneSceneStrategy — supporting pane
👉 В ListDetailPaneScaffold и SupportingPaneScaffold. Теперь поддерживают margins и edge-to-edge.
🔄 RTL-поддержка для pane expansion.
tive:adaptive-navigation3:1.3.0")

🔗 Полный changelog

#AndroidDev #JetpackCompose #Material3
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7👎4
⚙️ 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
👍53👎4
JetBrains исследует Compose HTML для Server-Side Rendering (SSR)

Frederik Pietzko из JetBrains решил проверить идею: что если Compose-компоненты рендерить в HTML на сервере, а не только в canvas/JS. В Compose добавляется обычная функция с типами:

@Composable
fun Card(title: String, count: Int) {
Div({ classes("card") }) {
H3 { Text(title) }
Span { Text(count.toString()) }
}
}


Идея — добавить функции Compose HTML renderToString / renderToBytes, чтобы один раз прогнать composition и получить строку HTML. Без браузера, без DOM, без recomposition и effects (как классический SSR). Пока речь идет только про JVM тартег

Мне нравится направление. Если Compose HTML получит нормальный серверный рендер, у Kotlin наконец появится шанс на type-safe fullstack без ухода в JS-фреймворки. Пока же это просто интересный разговор, который стоит почитать.

🔗 Источник

#Compose #ComposeHTML #Kotlin #SSR
👍27👎3
⚙️ mediaQuery в Compose: один вызов вместо кучи WindowSizeClass + posture + input

Официально появился mediaQuery — лямбда, которая смотрит на текущий UiMediaScope и возвращает boolean. Внутри можно проверять:
👉 windowWidth / windowHeight
👉 windowPosture (Tabletop, Book, Flat)
👉 pointerPrecision (Fine → Coarse → Blunt → None)
👉 keyboardKind (Physical / Virtual / None)
👉 hasCamera / hasMicrophone
👉 viewingDistance (Near / Medium / Far)

Включается одним флагом при запуске приложения:
ComposeUiFlags.isMediaQueryIntegrationEnabled = true


Для размеров, которые дёргаются часто, лучше использовать derivedMediaQuery (обёртка над derivedStateOf):
// Composable code
val narrowerThanMedium by derivedMediaQuery {
windowWidth < WindowSizeClass.WIDTH_DP_MEDIUM_LOWER_BOUND.dp
}
val narrowerThanExpanded by derivedMediaQuery {
windowWidth < WindowSizeClass.WIDTH_DP_EXPANDED_LOWER_BOUND.dp
}
when {
narrowerThanMedium -> SinglePaneLayout()
narrowerThanExpanded -> TwoPaneLayout()
else -> ThreePaneLayout()
}


Самый чистый кейс — foldable в tabletop:
// Composable code
if (mediaQuery { windowPosture == UiMediaScope.Posture.Tabletop }) {
TabletopLayout()
} else {
FlatLayout()
}


Это API не замена WindowSizeClass, но удобный единый вход для всего, что меняется в рантайме. Если пишете адаптив под foldable / desktop / TV — возьмите на заметку. Пока не перенесли в Compose Multiplatform.

Документация Media Query API

#Compose #JetpackCompose #Adaptive #UI #Android
Please open Telegram to view this post
VIEW IN TELEGRAM
1👍14👎5
🐱 Адаптивный 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
👍20👎4