Новости о продуктах

Что нового в выпуске Jetpack Compose от апреля 2026 г.

Время на чтение: 6 минут
Посмотреть профиль Meghan Mehta
Meghan Mehta Специалист по связям с разработчиками Android

Сегодня стабильной стала версия 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,. Если вы используете собственные детекторы жестов, проверьте их работу на разных типах устройств ввода, включая сенсорные экраны, мыши, сенсорные панели и стилусы. Убедитесь, что поддерживаются колесо прокрутки мыши и жесты на сенсорной панели.

beforeAndAfter.webp

Настройки хоста композиции по умолчанию (среда выполнения 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",
        )
    }
}
styles.webp

Ознакомьтесь с документацией и сообщите об ошибках здесь.

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()
    }
}

Вы можете размещать элементы автоматически или явно распределять их по нескольким строкам и столбцам для точности. Кроме того, она очень адаптивна: вы можете динамически перенастраивать дорожки и диапазоны сетки в зависимости от состояния устройства, например от того, находится ли оно в настольном режиме или как оно ориентировано. Благодаря этому интерфейс будет отлично выглядеть на устройствах любого типа.

Grid.gif

Ознакомьтесь с документацией и сообщите об ошибках здесь. 

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) })
    }
}
AnimationGif.gif

Ознакомьтесь с документацией и сообщите об ошибках здесь.

Новая реализация SlotTable (экспериментальная функция)

Мы добавили новую реализацию SlotTable, которая по умолчанию отключена в этом выпуске. SlotTable – это внутренняя структура данных, которую среда выполнения Compose использует для отслеживания состояния иерархии композиции, недействительности и повторной композиции, хранения запомненных значений и отслеживания всех метаданных композиции во время выполнения. Новая реализация призвана повысить производительность, особенно при случайных изменениях.

Чтобы попробовать новую функцию SlotTable, включите ComposeRuntimeFlags.isLinkBufferComposerEnabled. 

Начните программировать уже сегодня!

В Jetpack Compose уже есть много интересных API, и скоро появятся новые. Сейчас самое время перейти на Jetpack Compose. Мы всегда рады вашим отзывам и запросам на добавление функций (особенно в отношении @Experimental, которые ещё находятся в разработке). Оставить отзыв можно здесь. Желаем успехов!

Автор:
Продолжить чтение