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

Что нового в релизе Jetpack Compose от апреля 2026 года?

6 минут чтения
Посмотреть профиль Меган Мехты
Meghan Mehta разработчик-консультант, Android

Сегодня вышел стабильный релиз Jetpack Compose April '26. Этот релиз содержит версию 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 компонентом 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 для стилизации . 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 , которые ещё находятся в разработке) — пожалуйста, отправляйте их сюда . Удачного создания контента!

    Автор:
    Продолжить чтение
    ,
    Новости о продуктах

    Что нового в релизе Jetpack Compose от апреля 2026 года?

    6 минут чтения
    Посмотреть профиль Меган Мехты
    Meghan Mehta разработчик-консультант, Android

    Сегодня вышел стабильный релиз Jetpack Compose April '26. Этот релиз содержит версию 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 компонентом 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 для стилизации . 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 , которые ещё находятся в разработке) — пожалуйста, отправляйте их сюда . Удачного создания контента!

      Автор:
      Продолжить чтение
      ,
      Новости о продуктах

      Что нового в релизе Jetpack Compose от апреля 2026 года?

      6 минут чтения
      Посмотреть профиль Меган Мехты
      Meghan Mehta разработчик-консультант, Android

      Сегодня вышел стабильный релиз Jetpack Compose April '26. Этот релиз содержит версию 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 компонентом 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 для стилизации . 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 , которые ещё находятся в разработке) — пожалуйста, отправляйте их сюда . Удачного создания контента!

        Автор:
        Продолжить чтение
        ,
        Новости о продуктах

        Что нового в релизе Jetpack Compose от апреля 2026 года?

        6 минут чтения
        Посмотреть профиль Меган Мехты
        Meghan Mehta разработчик-консультант, Android

        Сегодня вышел стабильный релиз Jetpack Compose April '26. Этот релиз содержит версию 1.11 основных модулей Compose (см. полное сопоставление BOM ), инструменты отладки общих элементов, события трекпада и многое другое. У нас также есть несколько экспериментальных API, которые мы хотели бы, чтобы вы протестировали и оставили нам отзывы.

        To use today's release, upgrade your Compose BOM version to:

        implementation(platform("androidx.compose:compose-bom:2026.04.01"))

        Changes in Compose 1.11.0

        Coroutine execution in tests

        We're introducing a major update to how Compose handles test timing. Following the opt-in period announced in Compose 1.10, the v2 testing APIs are now the default, and the v1 APIs have been deprecated. The key change is a shift in the default test dispatcher. While the v1 APIs relied on the UnconfinedTestDispatcher , which executed coroutines immediately, the v2 APIs use the StandardTestDispatcher . This means that when a coroutine is launched in your tests, it is now queued and does not execute until the virtual clock is advanced.

        This better mimics production conditions, effectively flushing out race conditions and making your test suite significantly more robust and less flaky.

        To ensure your tests align with standard coroutine behavior and to avoid future compatibility issues, we strongly recommend migrating your test suite. Check out our comprehensive migration guide for API mappings and common fixes.

        Shared element improvements and animation tooling

        We've also added some handy visual debugging tools for shared elements and Modifier.animatedBounds . You can now see exactly what's happening under the hood—like target bounds, animation trajectories, and how many matches are found—making it much easier to spot why a transition might not be behaving as expected. To use the new tooling, simply surround your SharedTransitionLayout with the LookaheadAnimationVisualDebugging composable.

        LookaheadAnimationVisualDebugging(
            overlayColor = Color(0x4AE91E63),
            isEnabled = true,
            multipleMatchesColor = Color.Green,
            isShowKeylabelEnabled = false,
            unmatchedElementColor = Color.Red,
        ) {
            SharedTransitionLayout {
                CompositionLocalProvider(
                    LocalSharedTransitionScope provides this,
                ) {
                    // your content
                }
            }
        }

        Trackpad events

        We've revamped Compose support for trackpads, like built-in laptop trackpads, attachable trackpads for tablets, or external/virtual trackpads. Basic trackpad events will now generally be considered PointerType.Mouse events, aligning mouse and trackpad behavior to better match user expectations. Previously, these trackpad events were interpreted as fake touchscreen fingers of PointerType.Touch , which led to confusing user experiences. For example, clicking and dragging with a trackpad would scroll instead of selecting. By changing the pointer type these events have in the latest release of Compose, clicking and dragging with a trackpad will no longer scroll.

        We also added support for more complicated trackpad gestures as recognized by the platform since API 34, including two finger swipes and pinches . These gestures are automatically recognized by components like Modifier.scrollable and Modifier.transformable to have better behavior with trackpads.

        These changes improve behavior for trackpads across built-in components, with redundant touch slop removed, a more intuitive drag-and-drop starting gesture, double-click and triple-click selection in text fields, and desktop-styled context menus in text fields.

        To test trackpad behavior, there are new testing APIs with performTrackpadInput , which allow validating the behavior of your apps when being used with a trackpad. If you have custom gesture detectors, validate behavior across input types, including touchscreens, mice, trackpads, and styluses, and ensure support for mouse scroll wheels and trackpad gestures.

        beforeAndAfter.webp

        Composition host defaults (Compose runtime)

        We introduced HostDefaultProvider , LocalHostDefaultProvider , HostDefaultKey , and ViewTreeHostDefaultKey to supply host-level services directly through compose-runtime. This removes the need for libraries to depend on compose-ui for lookups, better supporting Kotlin Multiplatform. To link these values to the composition tree, library authors can use compositionLocalWithHostDefaultOf to create a CompositionLocal that resolves defaults from the host.

        Preview wrappers

        Android Studio custom previews is a new feature that allows you to define exactly how the contents of a Compose preview are displayed.

        By implementing the PreviewWrapperProvider interface and applying the new @PreviewWrapper annotation, you can easily inject custom logic, such as applying a specific Theme . The annotation can be applied to a function annotated with @Composable and @Preview or @MultiPreview , offering a generic, easy-to-use solution that works across preview features and significantly reduces repetitive code.

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

        Deprecations and removals

        • As announced in the Compose 1.10 blog post , we're deprecating Modifier.onFirstVisible() . Its name often led to misconceptions, particularly within lazy layouts, where it would trigger multiple times during scrolling. We recommend migrating to Modifier.onVisibilityChanged() , which allows for more precise manual tracking of visibility states tailored to your specific use case requirements.
        • The ComposeFoundationFlags.isTextFieldDpadNavigationEnabled flag was removed because D-pad navigation for TextFields is now always enabled by default. The new behavior ensures that the D-pad events from a gamepad or a TV remote first move the cursor in the given direction. The focus can move to another element only when the cursor reaches the end of the text.

        Upcoming APIs

        In the upcoming Compose 1.12.0 release, the compileSdk will be upgraded to compileSdk 37 , with AGP 9 and all apps and libraries that depend on Compose inheriting this requirement. We recommend keeping up to date with the latest released versions, as Compose aims to promptly adopt new compileSdks to provide access to the latest Android features. Be sure to check out the documentation here for more information on which version of AGP is supported for different API levels.

        In Compose 1.11.0, the following APIs are introduced as @Experimental , and we look forward to hearing your feedback as you explore them in your apps. Note that @Experimental APIs are provided for early evaluation and feedback and may undergo significant changes or removal in future releases.

        Styles (Experimental)

        We are introducing a new experimental foundation API for styling . The Style API is a new paradigm for customizing visual elements of components, which has traditionally been performed with modifiers. It is designed to unlock deeper, easier customization by exposing a standard set of styleable properties with simple state-based styling and animated transitions. With this new API, we're already seeing promising performance benefits . We plan to adopt Styles in Material components once the Style API stabilizes.

        A basic example of overriding a pressed state style background:

        @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

        Check out the documentation and file any bugs here .

        MediaQuery (Experimental)

        The new mediaQuery API provides a declarative and performant way to adapt your UI to its environment. It abstracts complex information retrieval into simple conditions within a UiMediaScope , ensuring recomposition only happens when needed.

        With support for a wide range of environmental signals—from device capabilities like keyboard types and pointer precision, to contextual states like window size and posture—you can build deeply responsive experiences. Performance is baked in with derivedMediaQuery to handle high-frequency updates, while the ability to override scopes makes testing and previews seamless across hardware configurations. Previously, to get access to certain device properties — like if a device was in tabletop mode — you'd need to write a lot of boilerplate to do so:

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

        Now, with UIMediaQuery , you can add the mediaQuery syntax to query device properties, such as if a device is in tabletop mode:

        @OptIn(ExperimentalMediaQueryApi::class)
        @Composable
        fun VideoPlayer() {
            if (mediaQuery { windowPosture == UiMediaScope.Posture.Tabletop }) {
                TabletopLayout()
            } else {
                FlatLayout()
            }
        }

        Check out the documentation and file any bugs here .

        Grid (Experimental)

        Grid is a powerful new API for building complex, two-dimensional layouts in Jetpack Compose. While Row and Column are great for linear designs, Grid gives you the structural control needed for screen-level architecture and intricate components without the overhead of a scrollable list. Grid allows you to define your layout using tracks, gaps, and cells, offering familiar sizing options like Dp , percentages, intrinsic content sizes, and flexible "Fr" units.

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

        You can place items automatically or explicitly span them across multiple rows and columns for precision. Best of all, it's highly adaptive—you can dynamically reconfigure your grid tracks and spans to respond to device states like tabletop mode or orientation changes, ensuring your UI looks great across form factors.

        Grid.gif

        Check out the documentation and file any bugs here .

        FlexBox (Experimental)

        FlexBox is a layout container designed for high performance, adaptive UIs. It manages item sizing and space distribution based on available container dimensions. It handles complex tasks like wrapping ( wrap ) and multi-axis alignment of items ( justifyContent, alignItems, alignContent ). It allows items to grow ( grow ) or shrink ( shrink ) to fill the container.

        @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

        Check out the documentation and file any bugs here .

        New SlotTable implementation (Experimental)

        We've introduced a new implementation of the SlotTable , which is disabled by default in this release. SlotTable is the internal data structure that the Compose runtime uses to track the state of your composition hierarchy, track invalidations/recompositions, store remembered values, and track all metadata of the composition at runtime. This new implementation is designed to improve performance, primarily around random edits.

        To try the new SlotTable , enable ComposeRuntimeFlags.isLinkBufferComposerEnabled .

        Start coding today!

        With so many exciting new APIs in Jetpack Compose, and many more coming up, it's never been a better time to migrate to Jetpack Compose . As always, we value your feedback and feature requests (especially on @Experimental features that are still baking) — please file them here . Happy composing!

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