Novidades sobre produtos

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

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

Hoje, o lançamento 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 (consulte 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 enviasse 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 grande atualização na forma como o Compose processa a programação de testes. 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 dispatcher 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 seus testes, ela é enfileirada e não é executada até que o relógio virtual seja avançado.

Isso imita melhor as condições de produção, eliminando efetivamente as condições de disputa 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 de corrotinas e evitar problemas de compatibilidade no futuro, recomendamos migrar seu pacote de testes. Confira nosso guia de migração abrangente para mapeamentos de API e correções comuns.

Melhorias no elemento compartilhado e ferramentas de animação

Também adicionamos algumas ferramentas visuais úteis 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 são encontradas. Assim, fica muito mais fácil identificar por que uma transição pode não estar se comportando como esperado. Para usar as novas ferramentas, basta envolver o SharedTransitionLayout com o elemento combinável 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

Renovamos o suporte do Compose para trackpads, como trackpads integrados de laptops, trackpads acopláveis para tablets ou trackpads externos/virtuais. Os eventos básicos do trackpad agora serão considerados eventos PointerType.Mouse, alinhando o comportamento do mouse e do trackpad para corresponder melhor às expectativas do usuário. Antes, esses eventos do trackpad eram interpretados como dedos falsos de tela sensível ao toque de PointerType.Touch, o que levava a experiências confusas para o usuário. Por exemplo, clicar e arrastar com um trackpad rola em vez de selecionar. Ao mudar o tipo de ponteiro desses eventos na versão mais recente do Compose, clicar e arrastar com um trackpad não vai mais rolar.

Também adicionamos suporte a gestos mais complicados do trackpad, reconhecidos pela plataforma desde a API 34, incluindo deslizamentos 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 todos os componentes integrados, com a remoção da folga de toque redundante, um gesto de arrastar e soltar mais intuitivo, seleção com clique duplo e triplo em campos de texto e menus de contexto no estilo desktop 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 telas sensíveis ao toque, mouses, trackpads e stylus, e garanta a compatibilidade com rodas de rolagem do mouse e gestos do trackpad.

beforeAndAfter.webp

Padrões do host de composição (tempo 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 resolva os padrões do host.

Visualizar wrappers

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

Ao implementar a interface PreviewWrapperProvider e aplicar a nova anotação @PreviewWrapper, é fácil injetar 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 de visualização 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, estamos descontinuando o Modifier.onFirstVisible(). O nome dele muitas vezes levava a equívocos, 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 adaptados 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 de TV primeiro movam 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ê fique por dentro das versões mais recentes, já que o Compose busca adotar rapidamente novos 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 de API. 

No Compose 1.11.0, as seguintes APIs são introduzidas como @Experimental. Aguardamos seu feedback enquanto você as explora nos seus apps. Os @Experimental APIs são fornecidos para avaliação e feedback iniciais e podem passar por mudanças significativas ou remoção em versões futuras.

Estilos (experimental)

Estamos lançando uma nova API experimental de base para estilização. A API Style é um novo paradigma para personalizar elementos visuais de componentes, o que tradicionalmente era feito com modificadores. Ele foi projetado para permitir uma personalização mais fácil e completa, expondo um conjunto padrão de propriedades estilizadas com estilização simples baseada em estado e transições animadas. Com essa nova API, já estamos vendo benefícios de performance promissores. Planejamos adotar estilos em componentes do Material quando a API Styles 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 informe os 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 em um UiMediaScope, garantindo que a recomposição só aconteça quando necessário.

Com suporte a 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. A performance é integrada com o derivedMediaQuery para lidar com atualizações de alta frequência, e a capacidade de substituir escopos facilita os testes e as prévias em configurações de hardware. Antes, para acessar determinadas propriedades do dispositivo, como se ele estava no modo de mesa, era necessário escrever muitos padrões: 

@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 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 informe os bugs aqui.

Grade (experimental)

O Grid é uma nova API eficiente 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. Com Grid, é possível definir seu layout usando faixas, lacunas e células, oferecendo opções de dimensionamento conhecidas, como Dp, porcentagens, tamanhos de conteúdo intrínsecos e unidades "Fr" flexíveis. 

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

Você pode posicionar os itens automaticamente ou abranger várias linhas e colunas para ter mais precisão. O melhor de tudo é que ele é altamente adaptável. Você pode reconfigurar dinamicamente as faixas e extensões da grade para responder a estados do dispositivo, como modo de mesa ou mudanças de orientação, garantindo que a interface tenha uma ótima aparência em todos os formatos.

Grid.gif

Confira a documentação e informe os bugs aqui. 

FlexBox (experimental)

O FlexBox é um contêiner de layout projetado para interfaces adaptáveis de alta performance. 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 texto (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 informe os bugs aqui.

Nova implementação do SlotTable (experimental)

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

Para testar o novo SlotTable, ative o ComposeRuntimeFlags.isLinkBufferComposerEnabled. 

Comece a programar hoje mesmo!

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

Escrito por:
Continuar lendo