Novidades da versão de abril de 2026 do Jetpack Compose
Leitura de 6 minutos
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 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 as condições de disputa e tornando seu pacote de testes muito 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
Reformulamos 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 ter um comportamento melhor 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 touch screens, mouses, trackpads e stylus, e garanta a compatibilidade com rodas de rolagem do mouse e gestos do trackpad.
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 da biblioteca podem usar compositionLocalWithHostDefaultOf para criar um CompositionLocal que resolva os padrões do host.
Visualizar wrappers
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 é 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
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 paraModifier.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.isTextFieldDpadNavigationEnabledfoi removida porque a navegação com o botão direcional paraTextFieldsagora 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 vão herdar esse requisito. Recomendamos que você mantenha as 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 profunda e fácil, expondo um repositório curricular de propriedades estilizadas com estilização simples baseada em estado e transições animadas. Com essa nova API, já estamos vendo benefícios de desempenho promissores. Planejamos adotar estilos em componentes do Material quando 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", ) } }
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 dentro de 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 derivedMediaQuery para processar atualizações de alta frequência, e a capacidade de substituir escopos facilita os testes e as prévias em várias configurações de hardware. Antes, para acessar determinadas propriedades do dispositivo, como se ele estava no modo de mesa, era necessário escrever muito código padrão:
@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 os intervalos 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.
Confira a documentação e informe os 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 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) }) } }
Confira a documentação e informe os bugs aqui.
Nova implementação do SlotTable (experimental)
Implementamos uma nova versã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 durante a execução. Essa nova implementação foi criada para melhorar o desempenho, principalmente em edições aleatórias.
Para testar o novo SlotTable, ative o ComposeRuntimeFlags.isLinkBufferComposerEnabled.
Comece a programar hoje!
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 pedidos de recursos (principalmente sobre recursos do @Experimental que ainda estão em desenvolvimento). Envie suas sugestões aqui. Divirta-se!
-
Novidades sobre produtosA depuração por Wi-Fi no Android agora é mais rápida, confiável e fácil de configurar do que nunca. Com o ADB Wi-Fi 2.0, apresentamos uma nova pilha de servidores e um tratamento de rede mais inteligente para resolver diretamente o feedback dos desenvolvedores sobre lacunas de usabilidade.
Steven Jenkins, Sherif Eid, Fabien Sanglard • Leitura de 1 minuto -
Novidades sobre produtosEsta é a versão estável final do Android Studio Quail. Os novos recursos do Android Studio permitem criar apps premium com IA de maneira eficiente e eficaz.
Amman Asfaw • Leitura de 5 minutos -
Novidades sobre produtosManter um ecossistema Android saudável é um compromisso compartilhado em que cada app e jogo tem um papel a desempenhar.
Raghavendra Hareesh Pottamsetty • Leitura de 4 minutos
Receba os insights mais recentes sobre desenvolvimento Android na sua caixa de entrada semanalmente.