Notícias sobre produtos

Novidades na versão de dezembro de 2025 do Jetpack Compose

Leitura de 6 minutos
Nick Butcher
Gerente de produtos

Hoje, a versão de dezembro de 2025 do Jetpack Compose está estável. Ela contém a versão 1.10 dos módulos principais do Compose e a versão 1.4 do Material 3 (consulte o mapeamento completo da BOM), adicionando novos recursos e grandes melhorias de desempenho.

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

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

Melhorias de desempenho

Sabemos que o desempenho de execução do seu app é muito importante para você e seus usuários. Por isso, o desempenho tem sido uma grande prioridade para a equipe do Compose. Essa versão traz várias melhorias, e você pode aproveitar todas elas fazendo upgrade para a versão mais recente. Nossos comparativos internos de rolagem mostram que o Compose agora corresponde ao desempenho que você teria ao usar Views:

janky.png

Comparativo de desempenho de rolagem comparando Views e Jetpack Compose em diferentes versões do Compose

Composição pausável na pré-busca lenta

A composição pausável na pré-busca lenta agora está ativada por padrão. Essa é uma mudança fundamental na forma como a execução do Compose agenda o trabalho, projetada para reduzir significativamente a instabilidade durante cargas de trabalho pesadas da interface.

Anteriormente, depois que uma composição era iniciada, ela precisava ser executada até a conclusão. Se uma composição fosse complexa, isso poderia bloquear a linha de execução principal por mais de um frame, fazendo com que a interface congelasse. Com a composição pausável, a execução agora pode "pausar" o trabalho se estiver ficando sem tempo e retomar o trabalho no próximo frame. Isso é particularmente eficaz quando usado com a pré-busca de layout lento para preparar frames com antecedência. As APIs Lazy layout CacheWindow introduzidas no Compose 1.9 são uma ótima maneira de pré-buscar mais conteúdo e aproveitar a composição pausável para produzir um desempenho de interface muito mais suave.

pausable.gif

A composição pausável combinada com a pré-busca lenta ajuda a reduzir a instabilidade

Também otimizamos o desempenho em outros lugares, com melhorias em Modifier.onPlaced, Modifier.onVisibilityChanged e outras implementações de modificadores. Vamos continuar investindo na melhoria do desempenho do Compose.

Novos recursos

Retain

O Compose oferece várias APIs para manter e gerenciar o estado em diferentes ciclos de vida. Por exemplo, remember mantém o estado em composições e rememberSavable/rememberSerializable para manter a atividade ou o processo de recriação.retain é uma nova API que fica entre essas APIs, permitindo que você mantenha valores em mudanças de configuração sem serem serializados, mas não em caso de encerramento do processo. Como retain não serializa seu estado, é possível manter objetos como expressões lambda, fluxos e objetos grandes, como bitmaps, que não podem ser facilmente serializados. Por exemplo, você pode usar retain para gerenciar um player de mídia (como o ExoPlayer) para garantir que a reprodução de mídia não seja interrompida por uma mudança de configuração.

  @Composable

fun MediaPlayer() {

    val applicationContext = LocalContext.current.applicationContext

    val exoPlayer = retain { ExoPlayer.Builder(applicationContext).apply { ... }.build() }

    ...

}

Agradecemos à comunidade AndroidDev (especialmente a equipe do Circuit), que influenciou e contribuiu para o design desse recurso.

Material 1.4

A versão 1.4.0 da biblioteca material3 adiciona vários novos componentes e melhorias:

  • TextField agora oferece uma versão experimental baseada em TextFieldState, que oferece um método mais robusto para gerenciar o estado do texto. Além disso, novas SecureTextFieldOutlinedSecureTextField variantes agora são oferecidas. O elemento combinável Text do Material Design agora oferece suporte ao comportamento de autoSize.
  • O componente de carrossel agora oferece uma nova HorizontalCenteredHeroCarousel variante.
  • TimePicker agora oferece suporte à alternância entre os modos de seletor e de entrada.
  • Uma alça de arrastar vertical ajuda os usuários a mudar o tamanho e/ou a posição de um painel adaptável.
centered-hero-carousel.webp

Carrossel de heróis centralizado horizontal

Observe que as APIs Material 3 Expressive continuam sendo desenvolvidas nas versões Alfa da biblioteca material3. Para saber mais, assista a esta palestra recente:

Novos recursos de animação

Continuamos expandindo nossas APIs de animação, incluindo atualizações para personalizar animações de elementos compartilhados.

Elementos compartilhados dinâmicos

Por padrão, as animações sharedElement() e sharedBounds() tentam animar

mudanças de layout sempre que uma chave correspondente é encontrada no estado de destino. No entanto, talvez você queira desativar essa animação dinamicamente com base em determinadas condições, como a direção da navegação ou o estado atual da interface.

Para controlar se a transição de elementos compartilhados ocorre, agora é possível personalizar o SharedContentConfig transmitido para rememberSharedContentState(). A propriedade isEnabled determina se o elemento compartilhado está ativo.

  SharedTransitionLayout {

        val transition = updateTransition(currentState)

        transition.AnimatedContent { targetState ->

            // Create the configuration that depends on state changing.

            fun animationConfig() : SharedTransitionScope.SharedContentConfig {

                return object : SharedTransitionScope.SharedContentConfig {

                    override val SharedTransitionScope.SharedContentState.isEnabled: Boolean

                        get() =

                            // determine whether to perform a shared element transition

                }

            }

}

Consulte a documentação para mais informações.

Modifier.skipToLookaheadPosition()

Um novo modificador, Modifier.skipToLookaheadPosition(), foi adicionado a essa versão, que mantém a posição final de um elemento combinável ao realizar animações de elementos compartilhados. Isso permite realizar transições como a animação do tipo "revelar", como pode ser visto no exemplo do Androidify com a revelação progressiva da câmera. Confira a dica de vídeo aqui para mais informações: 

Velocidade inicial em transições de elementos compartilhados

Essa versão adiciona uma nova API de transição de elementos compartilhados, prepareTransitionWithInitialVelocity, que permite transmitir uma velocidade inicial (por exemplo, de um gesto) para uma transição de elementos compartilhados:

  Modifier.fillMaxSize()

    .draggable2D(

        rememberDraggable2DState { offset += it },

        onDragStopped = { velocity ->

            // Set up the initial velocity for the upcoming shared element

            // transition.

            sharedContentStateForDraggableCat

                ?.prepareTransitionWithInitialVelocity(velocity)

            showDetails = false

        },

    )
fling-shared.gif

Uma transição de elementos compartilhados que começa com uma velocidade inicial de um gesto

Transições veladas

EnterTransitionExitTransition definem como um elemento combinável AnimatedVisibility/AnimatedContent aparece ou desaparece. Uma nova opção de véu experimental permite especificar uma cor para velar ou cobrir o conteúdo. Por exemplo, esmaecer uma camada preta semitransparente sobre o conteúdo:

veil_2.gif

Conteúdo animado velado: observe o véu semitransparente (ou scrim) sobre o conteúdo da grade durante a animação

  AnimatedContent(

    targetState = page,

    modifier = Modifier.fillMaxSize().weight(1f),

    transitionSpec = {

        if (targetState > initialState) {

            (slideInHorizontally { it } togetherWith

                    slideOutHorizontally { -it / 2 } + veilOut(targetColor = veilColor))

        } else {

            slideInHorizontally { -it / 2 } +

                    unveilIn(initialColor = veilColor) togetherWith slideOutHorizontally { it }

        }

    },

) { targetPage ->

    ...

}

Próximas mudanças

Descontinuação de Modifier.onFirstVisible

O Compose 1.9 introduziu Modifier.onVisibilityChangedModifier.onFirstVisible. Depois de analisar seu feedback, ficou claro que o contrato de Modifier.onFirstVisible não era possível de ser honrado deterministicamente, especificamente quando um item se torna visível pela primeira vez. Por exemplo, um layout lento pode descartar itens que rolam para fora da janela de visualização e, em seguida, compô-los novamente se eles rolarem de volta para a visualização. Nessa circunstância, o callback onFirstVisible seria acionado novamente, já que é um item recém-composto. Um comportamento semelhante também ocorreria ao navegar de volta para uma tela visitada anteriormente que continha onFirstVisible. Por isso, decidimos descontinuar esse modificador na próxima versão do Compose (1.11) e recomendamos a migração para onVisibilityChanged. Consulte a documentação para mais informações.

Envio de corrotinas em testes

Planejamos mudar o envio de corrotinas em testes para melhorar a instabilidade dos testes e detectar mais problemas. Atualmente, os testes usam o UnconfinedTestDispatcher, que difere do comportamento de produção. Por exemplo, efeitos podem ser executados imediatamente em vez de serem enfileirados. Em uma versão futura, planejamos introduzir uma nova API que usa StandardTestDispatcher por padrão para corresponder aos comportamentos de produção. Você pode testar o novo comportamento agora na versão 1.10:

  @get:Rule // also createAndroidComposeRule, createEmptyComposeRule

val rule = createComposeRule(effectContext = StandardTestDispatcher())

O uso do StandardTestDispatcher vai enfileirar tarefas. Portanto, você precisa usar mecanismos de sincronização como composeTestRule.waitForIdle() ou composeTestRule.runOnIdle(). Se o teste usar runTest, você precisará garantir que runTest e a regra do Compose compartilhem a mesma instância StandardTestDispatcher para sincronização.

  // 1. Create a SINGLE dispatcher instance

val testDispatcher = StandardTestDispatcher()



// 2. Pass it to your Compose rule

@get:Rule

val composeRule = createComposeRule(effectContext = testDispatcher)



@Test

// 3. Pass the *SAME INSTANCE* to runTest

fun myTest() = runTest(testDispatcher) {

    composeRule.setContent { /* ... */ }

}

Ferramentas

Ótimas APIs merecem ótimas ferramentas, e o Android Studio tem várias adições recentes para desenvolvedores do Compose:

Para ver essas ferramentas em ação, assista a esta demonstração recente:

Boa programação

Continuamos investindo no Jetpack Compose para oferecer as APIs e ferramentas necessárias para criar interfaces bonitas e avançadas. Valorizamos sua opinião. Por isso, compartilhe seu feedback sobre essas mudanças ou o que você gostaria de ver em seguida no nosso Issue Tracker.

Escrito por:

Continuar lendo