Сегодня вышел стабильный релиз Jetpack Compose от августа 2026 года! В этом релизе представлена версия 1.12 для основных модулей Compose (см. полное сопоставление BOM ), добавлены расширенные визуальные API, такие как градиенты сетки и поддержка широкого цветового охвата (WCG), структурные функции компоновки, например, именованные области в Grid , бесшовная интеграция с менеджером учетных данных Android, а также значительные улучшения в тестировании и производительности.
Чтобы обновить ваш проект до текущей версии, обновите версию Compose BOM до 2026.08.00 :
implementation(platform("androidx.compose:compose-bom:2026.08.00"))
Решающие перемены
- AGP и Compile SDK : В Compose 1.12 обновлен compileSdk до API 37, что требует как минимум AGP 9.1.2. Напоминаем, что Compose всегда будет использовать последнюю версию compileSdk. Подробнее об этом изменении можно узнать здесь .
-
Modifier.onFirstVisible()устарел : следует перейти на Modifier.onVisibilityChanged() , который обеспечивает более точное отслеживание пороговых значений видимости.
Графика
Градиенты сетки
В Compose 1.12 появилась MeshGradientPainter , которая поможет вам создавать многоточечные, органичные цветовые градиенты.

val rows = 1 val columns = 1 val gradientPainter = remember { MeshGradientPainter(rows, columns) { // Parameters: row, column, position, color setVertex(0, 0, Offset(0f, 0f), Color.Red) // Top-Left setVertex(0, 1, Offset(1f, 0f), Color.Blue) // Top-Right setVertex(1, 0, Offset(0f, 1f), Color.Green) // Bottom-Left setVertex(1, 1, Offset(1f, 1f), Color.Yellow) // Bottom-Right } } Box( modifier = modifier .aspectRatio(16/9f) .fillMaxWidth() .paint(gradientPainter) )
Для получения дополнительной информации и примеров см. документацию .
Поддержка широкого цветового охвата и HDR
Современные дисплеи обеспечивают расширенную цветопередачу и более высокий динамический диапазон. В Compose 1.12 включена полная поддержка рендеринга с широким цветовым охватом (P3) и HDR для графики, отрисовки и шейдеров Compose. Цвета, определенные в цветовых пространствах, отличных от sRGB (например, Display P3), сохраняются до момента рендеринга на платформе без ограничения цвета. Цвета будут безопасно возвращаться к sRGB, если они используют неподдерживаемое цветовое пространство (например, CieXyz, CieLab или Oklab), зависят от цветового пространства неподдерживаемой версии Android (например, Bt2020Hlg на Android 13 и ниже) или если приложение работает на Android 9 (API 28) и ниже.
Другие заметные изменения:
- В классы
GraphicsLayerиModifier.graphicsLayerдобавленаLayerOutsets, позволяющая расширить визуальные границы слоя за пределы его измеренного размера. ПрименениеLayerOutsetsпозволяет избежать неявного поведенияclipToBoundsпри перемещении слоя в буфер за пределами экрана.
Стили
На конференции Google I/O мы поделились своим первоначальным видением API стилей Compose — единого, высокопроизводительного способа стилизации компонентов. С тех пор мы продолжаем развивать базовую архитектуру, гарантирующую строгую типобезопасность и предсказуемую корректность, а также поддержку создания пользовательских систем дизайна.
Чтобы обеспечить корректную работу этого базового уровня, API останется экспериментальным, и вы можете ожидать изменений, нарушающих обратную совместимость.
Оптимизация во время выполнения
Перегрузка побочных эффектов, связанных с ключом
SideEffect теперь поддерживает аргументы клавиш, что позволяет запускать одноразовые побочные эффекты при изменении определенных клавиш. Это может привести к повышению производительности по сравнению с использованием LaunchedEffect или DisposableEffect , если вам не нужна сопрограмма или блок освобождения ресурсов. SideEffect работает до 90% быстрее, чем LaunchedEffect , и примерно на 20% быстрее, чем DisposableEffect . Обратите внимание, что SideEffect запускает свой эффект до DisposableEffect и LaunchedEffect , поэтому будьте осторожны при переносе существующих эффектов на этот API, особенно для LaunchedEffects , которые полагаются на запуск после завершения текущего кадра.
@Composable fun AnalyticsTracker(userId: String, screenName: String) { SideEffect(key1 = userId, key2 = screenName) { analytics.logScreenView(userId, screenName) } }
Анимация
-
DeferredTargetAnimationвышла из экспериментального статуса.
Интерактивные двухэтапные переходы
- Новые компоненты :
DeferredAnimatedContentиDeferredAnimatedVisibilityпозволяют создавать восхитительные двухэтапные переходы, например, для прогнозирующего отслеживания жестов при движении назад. - Ручное управление анимацией : Во время отложенной фазы перехода анимированные свойства (например, масштаб или смещение) теперь можно вручную изменять в режиме реального времени (например, отслеживать жест смахивания).
- Бесперебойная передача управления : После завершения отложенной фазы механизм перехода берет на себя управление и осуществляет бесперебойную передачу управления, включая передачу скорости, автоматическому переходу.
- Поддержка общих элементов : новый флаг
permitTransformDuringDeferredTransitionвSharedContentConfigопределяет, будут ли общие элементы визуально трансформироваться вместе со своими родительскими контейнерами во время фазы отложенного перехода.
val state = remember { DeferredTransitionState(initialScreen) } val transition = rememberDeferredTransition(state) if (predictiveBackInProgress) { state.defer(targetScreen) } else { state.animateTo(targetScreen) } transition.DeferredAnimatedContent( targetState = targetScreen, mutableTransformSpec = { MutableContentTransform { // Manually manipulate properties during the deferred phase initialContentTransform { scale = swipeProgress } } } ) { screen -> ScreenContent(screen) }
Ниже представлены два примера использования, в которых анимация, управляемая жестами, передается анимации, запускаемой по триггеру:

Интеграция текста, ввода и платформ
Редактируемое форматирование текста
Новые API-интерфейсы предлагают форматирование редактируемого текста в BasicTextField . Теперь вы можете программно применять и изменять встроенное форматирование символов и абзацев с помощью SpanStyle и ParagraphStyle через новый метод addStyle() внутри области видимости TextFieldBuffer (например, внутри textFieldState.edit { ... } или InputTransformation ). Кроме того, TextFieldBuffer предоставляет API-интерфейсы getSpanStyles() и getParagraphStyles() , которые возвращают объекты TrackedRange , позволяющие читать, обновлять или удалять примененные стили. В дополнение к созданию форматирования, TextFieldState теперь предоставляет свойство textStyles только для чтения, позволяющее запрашивать активные стили в диапазонах, а TextFieldBuffer предоставляет originalTextStyles для проверки состояния форматирования перед редактированием. Форматирование текста и пользовательские аннотации сохраняются при изменении конфигурации.
val state = rememberTextFieldState("Formatted text in Compose 1.12") // Apply bold and color styles to a range of text state.edit { addStyle( SpanStyle(fontWeight = FontWeight.Bold, color = Color.Blue), start = 0, end = 9 ) } // Query active styles from TextFieldState val currentStyles = state.textStyles
Выделение текста
Новый API SelectionState обеспечивает программное управление и наблюдение за выделением текста внутри SelectionContainer . Передача объекта SelectionState через rememberSelectionState() в SelectionContainer позволяет отображать selectedTexts как реактивный список AnnotatedStrings и предоставляет такие методы, как selectAll() , clear() , select(TextRange) и extendSelectionByWord() .
Кроме того, используйте getSelectableTexts() для получения всех выделяемых текстовых элементов в порядке расположения и выделения текста в элементах, входящих в составной контейнер SelectionContainer используя глобальный диапазон.
@Composable fun ProgrammaticSelectionExample() { val selectionState = rememberSelectionState() Column { Button( onClick = { selectionState.selectAll() }, modifier = Modifier.disableSelectionClearOnTap() ) { Text("Select All") } SelectionContainer(state = selectionState) { Text("Text content to be selected programmatically.") } } }
Интеграция с менеджером учетных данных
Теперь текстовые поля ввода интегрированы с диспетчером учетных данных Android (API 34+) через фреймворк автозаполнения (API ниже 34 обрабатывается androidx.credentials library ). Прикрепив новое свойство семантики credentialRequest к CredentialRequestData , текстовые поля ввода могут запрашивать пароли, сохраненные учетные данные или запросы на вход непосредственно в поток ввода пользователя.
@Composable fun LoginField(textFieldState: TextFieldState) { val credentialData = remember { CredentialRequestData( // Specify Credential Manager request options ) } BasicTextField( state = textFieldState, modifier = Modifier.semantics { credentialRequest = credentialData } ) }
Другие заметные изменения:
- Поддержка настроек вариативности шрифта в загружаемых шрифтах .
- Включена автоматическая прокрутка при перетаскивании выделенного текста за пределы области просмотра в
SelectionContainer. - Добавлена поддержка автоматических звуков взаимодействия (клики и навигация по фокусу) в компоненты Compose, с новым компонентом
SoundEffectOnInteraction, позволяющим отказаться от их использования. Обратите внимание, что в результате этого изменения обработчики кликов теперь должны вызываться из основного потока, что может повлиять на небольшое количество тестовых случаев. -
KeyboardTypeтеперь включены поляDate,Time,DateTimeиSignedDecimal. - Теперь
BasicSecureTextFieldпо умолчанию используетTextObfuscationMode.System, аRevealLastTypedслужит абсолютным переопределением.
Улучшения компоновки
Названия областей в сетке
Создание сложных 2D-макетов теперь стало проще благодаря именованным областям в компоненте @Experimental Grid . Вместо управления числовыми индексами столбцов и строк для элементов, вы можете определить семантические области в GridConfigurationScope и позиционировать компонуемые элементы по имени области.
@OptIn(ExperimentalGridApi::class) @Composable fun DashboardLayout() { Grid( config = { area("header", row = 0, column = 0, rowSpan = 1, columnSpan = 2) area("sidebar", row = 1, column = 0) area("content", row = 1, column = 1) gap(16.dp) } ) { HeaderSection(modifier = Modifier.gridItem(areaId = "header")) NavigationSidebar(modifier = Modifier.gridItem(areaId = "sidebar")) MainContentView(modifier = Modifier.gridItem(areaId = "content")) } }
Для получения более подробной информации см. документацию .
Производительность
Как и в каждом релизе, мы продолжаем инвестировать в повышение производительности Compose, чтобы гарантировать, что фреймворк поможет вам создавать красивые и высокопроизводительные приложения. В этом релизе мы сосредоточились на улучшении производительности при запуске, и теперь наблюдаем время до первого отображения (время, необходимое приложению для вывода первого кадра), сопоставимое с показателями Views в наших бенчмарках .

Модернизация средств тестирования и инструментов.
Синхронизация тестов
В Compose 1.12 представлены новые API для тестирования, разработанные для сокращения времени выполнения тестов и устранения нестабильности при выборке состояния:
-
hasPendingWork: Пассивно проверяет наличие незавершенной работы в пользовательском интерфейсе без продвижения таймера, что идеально подходит для циклов анимации, создаваемых вручную. -
runWithoutImplicitWait: Временно отключает неявную синхронизацию при пошаговом выполнении кадров с ручным вводом/выводом (например, в тестах анимации).
@Test fun testAnimationStateFast() { composeTestRule.mainClock.autoAdvance = false while (composeTestRule.hasPendingWork()) { composeTestRule.mainClock.advanceTimeByFrame() composeTestRule.waitForIdle() composeTestRule.runOnUiThread { composeTestRule.runWithoutImplicitWait { // This is most effective when querying multiple nodes in a single frame. // It prevents the redundant synchronization overhead that would // otherwise occur on every individual query. val box1 = composeTestRule.onNodeWithTag("Box1").fetchSemanticsNode() val box2 = composeTestRule.onNodeWithTag("Box2").fetchSemanticsNode() assertThat(box1.boundsInRoot.right).isAtMost(box2.boundsInRoot.left) } } } }
Другие заметные изменения:
- Теперь API
captureToImageпозволяет захватывать всплывающее окно или диалоговое окно вместе с его привязкой в одном растровом изображении. - Добавлено
onRootWithViewInteractionдля ограничения области действия семантического поиска Compose определенными представлениями Android. Это упрощает тестирование гибридных пользовательских интерфейсов, таких какRecyclerViews, без необходимости использования уникальных тестовых тегов в рабочем коде. - Теперь аннотации
@PreviewWrapperможно применять к пользовательским классам@MultiPreview, что позволяет создавать многократно используемые настройки предварительного просмотра (например, пользовательские темы) для нескольких компонентов.
Удачного сочинения!
Compose 1.12 делает разработку приложений проще и выразительнее, чем когда-либо, благодаря сетчатым градиентам, поддержке широкого цветового охвата, загружаемым вариативным шрифтам, интеграции с Credential Manager и более быстрым инструментам тестирования. Как всегда, мы ценим ваши отзывы, поэтому, пожалуйста, поделитесь своим мнением об этих изменениях или о том, что вы хотели бы увидеть в будущем, в нашем трекере проблем . Удачного создания!
Новости о продуктахС появлением Pixel 11 Pro Fold, Pixel Watch 5 и всего семейства Pixel пользователи получают возможность беспрепятственно переключаться между экранами разных размеров, различными положениями тела и интеллектуальными функциями.
Новости о продуктахСегодня мы официально отмечаем пятилетие с момента выхода Jetpack Compose 1.0. Начиная с версии 1.0, анонсированной 28 июля 2021 года, и заканчивая нашей последней версией 1.11, мы стали свидетелями значительного развития API, и мы хотим отметить это событие.
Rebecca Franks , Nick Butcher , Loryn Hairston • 4 мин чтения
Новости о продуктахЗа почти 5 лет с момента запуска Jetpack Compose мы инвестировали в то, чтобы предоставить вам все функции, производительность и инструменты, необходимые для создания потрясающих пользовательских интерфейсов на самых разных устройствах Android.
Nick Butcher • 2 мин чтения
Получайте еженедельно самые свежие новости о разработке Android прямо на свою электронную почту.


