Notícias sobre produtos

Novidades da versão de abril de 2026 do Jetpack Compose

Leitura de 6 min
Ver o perfil de Meghan Mehta
Meghan Mehta Mediador de desenvolvedores, Android

Hoje, a versão de abril de 2026 do Jetpack Compose está estável. Esta versão contém a versão 1.11 dos módulos principais do Compose (confira o mapeamento completo da BoM), ferramentas de depuração de elementos compartilhados, eventos de trackpad e muito mais. Também temos algumas APIs experimentais que gostaríamos que você testasse e nos desse feedback.

Para usar a versão de hoje, faça upgrade da versão da BOM do Compose para:

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

Mudanças no Compose 1.11.0

Execução de corrotinas em testes

Estamos lançando uma atualização importante na forma como o Compose lida com o tempo de teste. Após o período de ativação anunciado no Compose 1.10, as APIs de teste v2 agora são o padrão, e as APIs v1 foram descontinuadas. A principal mudança é uma alteração no agente de teste padrão. Enquanto as APIs v1 dependiam do UnconfinedTestDispatcher, que executava corrotinas imediatamente, as APIs v2 usam o StandardTestDispatcher. Isso significa que, quando uma corrotina é iniciada nos testes, ela é colocada em fila e não é executada até que o relógio virtual seja adiantado.

Isso imita melhor as condições de produção, eliminando disputas e tornando seu pacote de testes significativamente mais robusto e menos instável.

Para garantir que seus testes estejam alinhados com o comportamento padrão das corrotinas e evitar problemas de compatibilidade no futuro, recomendamos migrar seu pacote de testes. Confira nosso guia de migração completo para mapeamentos de API e correções comuns.

Melhorias em elementos compartilhados e ferramentas de animação

Também adicionamos algumas ferramentas visuais de depuração para elementos compartilhados e Modifier.animatedBounds. Agora você pode ver exatamente o que está acontecendo nos bastidores, como limites de destino, trajetórias de animação e quantas correspondências foram encontradas, o que facilita muito identificar por que uma transição pode não estar se comportando como esperado. Para usar as novas ferramentas, basta colocar o SharedTransitionLayout no elemento de composição LookaheadAnimationVisualDebugging. 

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

Eventos do trackpad

Reformulamos o suporte do Compose para trackpads, como os integrados em laptops, os que podem ser conectados a tablets ou os externos/virtuais. Os eventos básicos do trackpad agora serão considerados eventos PointerType.Mouse, alinhando o comportamento do mouse e do trackpad para atender melhor às expectativas do usuário. Antes, esses eventos do trackpad eram interpretados como toques falsos na tela touch de PointerType.Touch, o que levava a experiências confusas para o usuário. Por exemplo, clicar e arrastar com um trackpad rolava a tela em vez de selecionar. Ao mudar o tipo de ponteiro que esses eventos têm na versão mais recente do Compose, clicar e arrastar com um trackpad não vai mais rolar a tela.

Também adicionamos suporte para gestos mais complexos no trackpad, reconhecidos pela plataforma desde a API 34, incluindo deslizar com dois dedos e gestos de pinça. Esses gestos são reconhecidos automaticamente por componentes como Modifier.scrollable e Modifier.transformable para melhorar o comportamento com trackpads.

Essas mudanças melhoram o comportamento dos trackpads em componentes integrados, com a remoção da folga de toque redundante, um gesto de início de arrastar e soltar mais intuitivo, seleção de clique duplo e triplo em campos de texto e menus de contexto no estilo de computador em campos de texto.

Para testar o comportamento do trackpad, há novas APIs de teste com performTrackpadInput, que permitem validar o comportamento dos apps quando usados com um trackpad. Se você tiver detectores de gestos personalizados, valide o comportamento em todos os tipos de entrada, incluindo touch screens, mouses, trackpads e stylus, e garanta suporte para rodas de rolagem de mouse e gestos de trackpad.

beforeAndAfter.webp

Padrões do host de composição (ambiente de execução do Compose)

Introduzimos HostDefaultProvider, LocalHostDefaultProvider, HostDefaultKey e ViewTreeHostDefaultKey para fornecer serviços no nível do host diretamente pelo compose-runtime. Isso elimina a necessidade de as bibliotecas dependerem de compose-ui para pesquisas, oferecendo melhor suporte ao Kotlin Multiplatform. Para vincular esses valores à árvore de composição, os autores de bibliotecas podem usar compositionLocalWithHostDefaultOf para criar um CompositionLocal que resolve os padrões do host.

Wrappers de visualização

As visualizações personalizadas do Android Studio são um novo recurso que permite definir exatamente como o conteúdo de uma visualização do Compose é mostrado.

Ao implementar a interface PreviewWrapperProvider e aplicar a nova anotação @PreviewWrapper, é possível injetar facilmente uma lógica personalizada, como aplicar um Theme específico. A anotação pode ser aplicada a uma função anotada com @Composable e @Preview ou @MultiPreview, oferecendo uma solução genérica e fácil de usar que funciona em recursos em fase de pré-lançamento e reduz significativamente o código repetitivo.

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

Descontinuações e remoções

  • Como anunciado na postagem do blog sobre o Compose 1.10, o Modifier.onFirstVisible() será descontinuado. O nome dele costumava causar confusão, principalmente em layouts lentos, em que ele era acionado várias vezes durante a rolagem. Recomendamos migrar para o Modifier.onVisibilityChanged(), que permite um rastreamento manual mais preciso dos estados de visibilidade, adaptado aos requisitos específicos do seu caso de uso.
  • A flag ComposeFoundationFlags.isTextFieldDpadNavigationEnabled foi removida porque a navegação com o botão direcional para TextFields agora está sempre ativada por padrão. O novo comportamento garante que os eventos do botão direcional de um gamepad ou controle remoto da TV movam primeiro o cursor na direção indicada. O foco só pode ser movido para outro elemento quando o cursor chega ao final do texto.

Próximas APIs

Na próxima versão do Compose 1.12.0, o compileSdk será atualizado para compileSdk 37, com o AGP 9 e todos os apps e bibliotecas que dependem do Compose herdando esse requisito. Recomendamos que você se mantenha atualizado com as versões de lançamento mais recentes, já que o Compose tem como objetivo adotar rapidamente novas compileSdks para oferecer acesso aos recursos mais recentes do Android. Confira a documentação aqui para mais informações sobre qual versão do AGP é compatível com diferentes níveis da API. 

No Compose 1.11.0, as APIs a seguir foram introduzidas como @Experimental, e queremos saber sua opinião sobre elas nos seus apps. As @Experimental APIs são fornecidas para avaliação e feedback antecipados e podem passar por mudanças significativas ou ser removidas em versões futuras.

Estilos (experimental)

Estamos lançando uma nova API experimental de base para estilo. A API Style é um novo paradigma para personalizar elementos visuais de componentes, o que tradicionalmente é feito com modificadores. Ele foi projetado para permitir uma personalização mais profunda e fácil, expondo um repositório curricular de propriedades estilizadas com estilo simples baseado em estado e transições animadas. Com essa nova API, já estamos vendo benefícios de desempenho promissores. Planejamos adotar estilos nos componentes do Material Design assim que a API Style se estabilizar.

Um exemplo básico de substituição de um plano de fundo de estilo de estado pressionado:

@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

Confira a documentação e registre bugs aqui.

MediaQuery (experimental)

A nova API mediaQuery oferece uma maneira declarativa e eficiente de adaptar sua interface ao ambiente. Ele abstrai a recuperação de informações complexas em condições simples dentro de um UiMediaScope, garantindo que a recomposição só aconteça quando necessário.

Com suporte para uma ampla variedade de indicadores ambientais, desde recursos do dispositivo, como tipos de teclado e precisão do ponteiro, até estados contextuais, como tamanho e posição da janela, é possível criar experiências altamente responsivas. O desempenho é integrado ao derivedMediaQuery para lidar com atualizações de alta frequência, enquanto a capacidade de substituir escopos facilita os testes e as prévias em diferentes configurações de hardware. Antes, para acessar determinadas propriedades do dispositivo, como se ele estava no modo de mesa, era necessário escrever muitos códigos boilerplate: 

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

Agora, com o UIMediaQuery, é possível adicionar a sintaxe mediaQuery para consultar as propriedades do dispositivo, como se ele está no modo de mesa:

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

Confira a documentação e registre bugs aqui.

Grade (experimental)

A Grid é uma nova API avançada para criar layouts bidimensionais complexos no Jetpack Compose. Embora Row e Column sejam ótimos para designs lineares, Grid oferece o controle estrutural necessário para arquitetura no nível da tela e componentes complexos sem a sobrecarga de uma lista rolável. O Grid permite definir o layout usando faixas, lacunas e células, oferecendo opções de dimensionamento conhecidas, como Dp, porcentagens, tamanhos de conteúdo intrínsecos e unidades flexíveis "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()
    }
}

É possível posicionar itens automaticamente ou distribuí-los explicitamente em várias linhas e colunas para maior precisão. O melhor de tudo é que ele é altamente adaptável: você pode reconfigurar dinamicamente as faixas e os intervalos da grade para responder a estados do dispositivo, como o modo de mesa ou mudanças de orientação, garantindo que a interface fique ótima em todos os formatos.

Grid.gif

Confira a documentação e registre bugs aqui. 

FlexBox (experimental)

O FlexBox é um contêiner de layout projetado para interfaces adaptáveis de alto desempenho. Ele gerencia o dimensionamento de itens e a distribuição de espaço com base nas dimensões disponíveis do contêiner.  Ele lida com tarefas complexas, como quebra de linha (wrap) e alinhamento de itens em vários eixos (justifyContent, alignItems, alignContent). Ele permite que os itens aumentem (grow) ou diminuam (shrink) para preencher o contêiner. 

@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

Confira a documentação e registre bugs aqui.

Nova implementação de SlotTable (experimental)

Introduzimos uma nova implementação do SlotTable, que está desativada por padrão nesta versão. SlotTable é a estrutura de dados interna que o ambiente de execução do Compose usa para acompanhar o estado da hierarquia de composição, acompanhar invalidações/recomposições, armazenar valores lembrados e acompanhar todos os metadados da composição no ambiente de execução. Essa nova implementação foi projetada para melhorar o desempenho, principalmente em relação a edições aleatórias.

Para testar o novo SlotTable, ative ComposeRuntimeFlags.isLinkBufferComposerEnabled. 

Comece a programar hoje mesmo!

Com tantas APIs novas e interessantes no Jetpack Compose e muitas outras que ainda vão chegar, nunca houve um momento melhor para migrar para o Jetpack Compose.  Como sempre, valorizamos seu feedback e suas solicitações de recursos (especialmente sobre os recursos do @Experimental que ainda estão em desenvolvimento). Envie-os aqui. Divirta-se!

Escrito por:
Continue lendo