Сегодня стабильной стала версия Jetpack Compose, выпущенная в апреле 2026 г. В этот выпуск входит версия 1.11 основных модулей Compose (см. полное сопоставление BOM), инструменты отладки общих элементов, события сенсорной панели и многое другое. Мы также предлагаем вам попробовать несколько экспериментальных API и поделиться своим мнением о них.
Чтобы использовать сегодняшний выпуск, обновите версию Compose BOM до:
implementation(platform("androidx.compose:compose-bom:2026.04.01"))
Изменения в Compose 1.11.0
Выполнение сопрограмм в тестах
Мы внесли значительные изменения в то, как Compose обрабатывает время тестирования. После периода согласия, объявленного в Compose 1.10, API для тестирования версии 2 теперь используются по умолчанию, а API версии 1 больше не поддерживаются. Основное изменение – это переход на диспетчер тестирования по умолчанию. В API версии 1 использовался UnconfinedTestDispatcher, который выполнял сопрограммы немедленно, а в API версии 2 используется StandardTestDispatcher. Это означает, что при запуске сопрограммы в тестах она теперь помещается в очередь и не выполняется, пока не будет продвинут виртуальный таймер.
Это позволяет лучше имитировать условия производства, эффективно выявлять состояния гонки и делать набор тестов значительно более надежным и менее нестабильным.
Чтобы ваши тесты соответствовали стандартному поведению сопрограмм и избежать проблем с совместимостью в будущем, мы настоятельно рекомендуем перенести набор тестов. Ознакомьтесь с нашим подробным руководством по переходу, в котором рассказывается, как сопоставить API и устранить распространенные проблемы.
Улучшения общих элементов и инструментов анимации
Мы также добавили удобные инструменты визуальной отладки для общих элементов и Modifier.animatedBounds. Теперь вы можете видеть, что происходит под капотом, например границы цели, траектории анимации и количество найденных совпадений. Это позволяет понять, почему переход может работать не так, как ожидалось. Чтобы использовать новый инструмент, просто оберните SharedTransitionLayout в composable-функцию LookaheadAnimationVisualDebugging.
LookaheadAnimationVisualDebugging( overlayColor = Color(0x4AE91E63), isEnabled = true, multipleMatchesColor = Color.Green, isShowKeylabelEnabled = false, unmatchedElementColor = Color.Red, ) { SharedTransitionLayout { CompositionLocalProvider( LocalSharedTransitionScope provides this, ) { // your content } } }
События сенсорной панели
Мы улучшили поддержку трекпадов в Compose, например встроенных трекпадов ноутбуков, подключаемых трекпадов для планшетов или внешних/виртуальных трекпадов. Теперь основные события трекпада будут считаться событиями PointerType.Mouse, чтобы поведение мыши и трекпада лучше соответствовало ожиданиям пользователей. Раньше эти события сенсорной панели интерпретировались как ложные касания сенсорного экрана пальцами PointerType.Touch, что приводило к неудобствам для пользователей. Например, при нажатии и перетаскивании на сенсорной панели будет выполняться прокрутка, а не выделение. В последнем выпуске Compose тип указателя для этих событий был изменен, поэтому при нажатии и перетаскивании с помощью сенсорной панели прокрутка больше не выполняется.
Мы также добавили поддержку более сложных жестов на сенсорной панели, которые распознаются платформой начиная с API 34, включая пролистывание двумя пальцами и сведение пальцев. Эти жесты автоматически распознаются такими компонентами, как Modifier.scrollable и Modifier.transformable, чтобы улучшить работу с трекпадом.
Эти изменения улучшают работу трекпадов, встроенных в устройства, за счет удаления избыточного люфта, более интуитивного жеста перетаскивания, выбора двойным и тройным нажатием в текстовых полях и контекстных меню в текстовых полях, как на компьютере.
Чтобы проверить, как приложение работает с сенсорной панелью, используйте новые API для тестирования с performTrackpadInput,. Если вы используете собственные детекторы жестов, проверьте их работу на разных типах устройств ввода, включая сенсорные экраны, мыши, сенсорные панели и стилусы. Убедитесь, что поддерживаются колесо прокрутки мыши и жесты на сенсорной панели.
Настройки хоста композиции по умолчанию (среда выполнения Compose)
Мы добавили HostDefaultProvider, LocalHostDefaultProvider, HostDefaultKey и ViewTreeHostDefaultKey, чтобы предоставлять сервисы на уровне хоста напрямую через compose-runtime. Это позволяет библиотекам не зависеть от compose-ui при поиске и лучше поддерживать Kotlin Multiplatform. Чтобы связать эти значения с деревом композиции, авторы библиотек могут использовать compositionLocalWithHostDefaultOf для создания CompositionLocal, который разрешает значения по умолчанию от хоста.
Предварительный просмотр контейнеров
Специальные настройки предпросмотра в Android Studio – это новая функция, которая позволяет задавать, как именно будет отображаться контент в предпросмотре Compose.
Реализовав интерфейс PreviewWrapperProvider и применив новую аннотацию @PreviewWrapper, вы можете легко внедрить собственную логику, например применить определенный Theme. Аннотацию можно применить к функции, аннотированной с помощью @Composable и @Preview или @MultiPreview. Это универсальное и простое в использовании решение, которое работает с предварительными версиями функций и значительно сокращает количество повторяющегося кода.
class ThemeWrapper: PreviewWrapperProvider { @Composable override fun Wrap(content: @Composable (() -> Unit)) { JetsnackTheme { content() } } } @PreviewWrapper(ThemeWrapper::class) @Preview @Composable private fun ButtonPreview() { // JetsnackTheme in effect Button(onClick = {}) { Text(text = "Demo") } }
Прекращение поддержки и удаление
- Как мы сообщали в записи блога о Compose 1.10, поддержка
Modifier.onFirstVisible()прекращается. Его название часто вводило в заблуждение, особенно при использовании ленивой загрузки, когда оно срабатывало несколько раз при прокрутке. Рекомендуем перейти наModifier.onVisibilityChanged(), который позволяет точнее отслеживать состояния видимости вручную в соответствии с вашими требованиями. - Флаг
ComposeFoundationFlags.isTextFieldDpadNavigationEnabledбыл удален, поскольку навигация с помощью d-pad дляTextFieldsтеперь всегда включена по умолчанию. Новое поведение гарантирует, что события D-pad с геймпада или пульта дистанционного управления телевизора сначала перемещают курсор в заданном направлении. Фокус можно переместить на другой элемент, только когда курсор достигнет конца текста.
Будущие API
В предстоящем выпуске Compose 1.12.0 compileSdk будет обновлен до compileSdk 37 с AGP 9. Все приложения и библиотеки, зависящие от Compose, унаследуют это требование. Мы рекомендуем использовать последние версии, так как Compose быстро адаптируется к новым версиям compileSdks, чтобы предоставить вам доступ к новейшим функциям Android. Обязательно ознакомьтесь с документацией, чтобы узнать, какие версии AGP поддерживаются для разных уровней API.
В Compose 1.11.0 представлены следующие API с пометкой @Experimental. Мы будем рады узнать ваше мнение о них. Обратите внимание, что @Experimental APIs предоставляются для ранней оценки и получения отзывов. В будущих выпусках они могут быть значительно изменены или удалены.
Стили (экспериментальная функция)
Мы представляем новый экспериментальный базовый API для стилизации. Style API – это новая парадигма для настройки визуальных элементов компонентов, которая традиционно выполнялась с помощью модификаторов. Он позволяет выполнять более глубокую и простую настройку, предоставляя набор стандартов настраиваемых свойств с простым стилем на основе состояния и анимированными переходами. Новый API уже показал многообещающие результаты. Мы планируем добавить стили в компоненты Material, как только API стилей станет стабильным.
Простой пример переопределения фона для состояния нажатия:
@Composable fun LoginButton(modifier: Modifier = Modifier) { Button( onClick = { // Login logic }, modifier = modifier, style = { background( Brush.linearGradient( listOf(lightPurple, lightBlue) ) ) width(75.dp) height(50.dp) textAlign(TextAlign.Center) externalPadding(16.dp) pressed { background( Brush.linearGradient( listOf(Color.Magenta, Color.Red) ) ) } } ){ Text( text = "Login", ) } }
Ознакомьтесь с документацией и сообщите об ошибках здесь.
MediaQuery (экспериментальная функция)
Новый API mediaQuery позволяет адаптировать интерфейс к среде декларативным и эффективным способом. Он абстрагирует сложный поиск информации в простые условия в рамках UiMediaScope, гарантируя, что перекомпоновка происходит только при необходимости.
Поддержка широкого спектра сигналов среды – от возможностей устройства, таких как типы клавиатуры и точность указателя, до контекстных состояний, таких как размер окна и положение, – позволяет создавать глубоко адаптивные интерфейсы. derivedMediaQuery обеспечивает высокую производительность при частых обновлениях, а возможность переопределять области действия позволяет легко тестировать и просматривать контент на разных конфигурациях оборудования. Раньше, чтобы получить доступ к определенным свойствам устройства, например узнать, находится ли оно в настольном режиме, нужно было написать много стандартного кода:
@Composable fun isTabletopPosture( context: Context = LocalContext.current ): Boolean { val windowLayoutInfo by WindowInfoTracker .getOrCreate(context) .windowLayoutInfo(context) .collectAsStateWithLifecycle(null) return windowLayoutInfo.displayFeatures.any { displayFeature -> displayFeature is FoldingFeature && displayFeature.state == FoldingFeature.State.HALF_OPENED && displayFeature.orientation == FoldingFeature.Orientation.HORIZONTAL } } @Composable fun VideoPlayer() { if(isTabletopPosture()) { TabletopLayout() } else { FlatLayout() } }
Теперь с помощью UIMediaQuery можно добавить синтаксис mediaQuery, чтобы запрашивать свойства устройства, например, находится ли оно в настольном режиме:
@OptIn(ExperimentalMediaQueryApi::class) @Composable fun VideoPlayer() { if (mediaQuery { windowPosture == UiMediaScope.Posture.Tabletop }) { TabletopLayout() } else { FlatLayout() } }
Ознакомьтесь с документацией и сообщите об ошибках здесь.
Сетка (экспериментальная функция)
Grid – это новый мощный API для создания сложных двумерных макетов в Jetpack Compose. Row и Column хорошо подходят для линейных макетов, а Grid позволяет управлять структурой на уровне экрана и создавать сложные компоненты без необходимости использовать прокручиваемый список. Grid позволяет задавать макет с помощью дорожек, промежутков и ячеек, используя знакомые варианты размеров, такие как Dp, проценты, внутренние размеры контента и гибкие единицы fr.
@OptIn(ExperimentalGridApi::class) @Composable fun GridExample() { Grid( config = { repeat(4) { column(0.25f) } repeat(2) { row(0.5f) } gap(16.dp) } ) { Card1(modifier = Modifier.gridItem(rowSpan = 2) Card2(modifier = Modifier.gridItem(colmnSpan = 3) Card3(modifier = Modifier.gridItem(columnSpan = 2) Card4() } }
Вы можете размещать элементы автоматически или явно распределять их по нескольким строкам и столбцам для точности. Кроме того, она очень адаптивна: вы можете динамически перенастраивать дорожки и диапазоны сетки в зависимости от состояния устройства, например от того, находится ли оно в настольном режиме или как оно ориентировано. Благодаря этому интерфейс будет отлично выглядеть на устройствах любого типа.
Ознакомьтесь с документацией и сообщите об ошибках здесь.
FlexBox (экспериментальная функция)
FlexBox – это контейнер макета, предназначенный для высокопроизводительных адаптивных пользовательских интерфейсов. Он управляет размерами элементов и распределением пространства на основе доступных размеров контейнера. Он позволяет выполнять сложные задачи, такие как перенос (wrap) и выравнивание элементов по нескольким осям (justifyContent, alignItems, alignContent). Элементы могут увеличиваться (grow) или уменьшаться (shrink), чтобы заполнить контейнер.
@OptIn(ExperimentalFlexBoxApi::class) fun FlexBoxWrapping(){ FlexBox( config = { wrap(FlexWrap.Wrap) gap(8.dp) } ) { RedRoundedBox() BlueRoundedBox() GreenRoundedBox(modifier = Modifier.width(350.dp).flex { grow(1.0f) }) OrangeRoundedBox(modifier = Modifier.width(200.dp).flex { grow(0.7f) }) PinkRoundedBox(modifier = Modifier.width(200.dp).flex { grow(0.3f) }) } }
Ознакомьтесь с документацией и сообщите об ошибках здесь.
Новая реализация SlotTable (экспериментальная функция)
Мы добавили новую реализацию SlotTable, которая по умолчанию отключена в этом выпуске. SlotTable – это внутренняя структура данных, которую среда выполнения Compose использует для отслеживания состояния иерархии композиции, недействительности и повторной композиции, хранения запомненных значений и отслеживания всех метаданных композиции во время выполнения. Новая реализация призвана повысить производительность, особенно при случайных изменениях.
Чтобы попробовать новую функцию SlotTable, включите ComposeRuntimeFlags.isLinkBufferComposerEnabled.
Начните программировать уже сегодня!
В Jetpack Compose уже есть много интересных API, и скоро появятся новые. Сейчас самое время перейти на Jetpack Compose. Мы всегда рады вашим отзывам и запросам на добавление функций (особенно в отношении @Experimental, которые ещё находятся в разработке). Оставить отзыв можно здесь. Желаем успехов!
-
Новости о продуктахСегодня мы расскажем, как будем развивать эту концепцию. Google Play всегда рядом с пользователями. Вкладка "Вы" стала персональным центром управления для более чем 250 миллионов активных пользователей за месяц, а наша единая игровая платформа объединяет более 700 миллионов игровых профилей.
Paul Feng • Время на чтение: 3 минуты -
Новости продуктовРазработчикам Android доступно множество агентов, LLM, инструментов и интерфейсов командной строки (CLI) для разработки приложений. Наша цель – помочь вам создавать красивые и качественные приложения для Android, независимо от того, какой способ разработки вы выберете.
Simona Milanovic • Время на чтение: 4 минуты -
Новости о продуктахМы постоянно расширяем возможности платформы подписок в Google Play, чтобы помочь вам развивать бизнес, адаптироваться к новым бизнес-моделям и привлекать пользователей.
Sheenam Mittal • Время на чтение: 4 минуты
Получайте свежие новости о разработке приложений для Android на свою электронную почту каждую неделю.