Home / Aplicativo móvel / O que há de novo na versão Jetpack Compose de 26 de abril

O que há de novo na versão Jetpack Compose de 26 de abril

O que há de novo na versão Jetpack Compose de 26 de abril

Postado por Meghan Mehta, engenheira de relações com desenvolvedores Android

O que há de novo na versão Jetpack Compose de 26 de abril

Hoje, a versão de 26 de abril 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 adoraríamos que você experimentasse e sobre as quais nos desse feedback.

Para usar a versão de hoje, atualize seu Compor BOM versão para:

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

Mudanças no Compose 1.11.0

Execução de corrotina em testes

Estamos introduzindo uma grande atualização na forma como o Compose lida com o tempo de teste. Após o período de aceitaçã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 mudança no despachante de teste padrão. Embora as APIs v1 dependessem de UnconfinedTestDispatcherque executava corrotinas imediatamente, as APIs v2 usam o StandardTestDispatcher. Isso significa que quando uma corrotina é iniciada em seus testes, ela agora fica na fila 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 corrida e tornando seu conjunto de testes significativamente mais robusto e menos instável.

Para garantir que seus testes estejam alinhados com o comportamento padrão da corrotina e para evitar futuros problemas de compatibilidade, recomendamos fortemente a migração do seu conjunto de testes. Confira nosso abrangente guia de migração para mapeamentos de API e correções comuns.

Melhorias em elementos compartilhados e ferramentas de animação

Também adicionamos algumas ferramentas úteis de depuração visual para elementos compartilhados e Modifier.animatedBounds. Agora você pode ver exatamente o que está acontecendo nos bastidores, como limites de alvo, trajetórias de animação e quantas correspondências são encontradas, tornando muito mais fácil identificar por que uma transição pode não estar se comportando conforme o esperado. Para usar as novas ferramentas, basta cercar seu SharedTransitionLayout com o LookaheadAnimationVisualDebugging combinável.

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 para laptop, trackpads conectáveis ​​para tablets ou trackpads externos/virtuais. Os eventos básicos do trackpad agora serão geralmente considerados PointerType.Mouse eventos, alinhando o comportamento do mouse e do trackpad para melhor atender às expectativas do usuário. Anteriormente, esses eventos do trackpad eram interpretados como dedos falsos na tela sensível ao toque de PointerType.Toucho que levou a experiências confusas do usuário. Por exemplo, clicar e arrastar com um trackpad rolaria em vez de selecionar. Ao alterar o tipo de ponteiro que esses eventos têm na versão mais recente do Compose, clicar e arrastar com um trackpad não rolará mais.

Também adicionamos suporte para gestos mais complicados do trackpad, conforme reconhecido pela plataforma desde a API 34, incluindo deslizar dois dedos e beliscões. Esses gestos são reconhecidos automaticamente por componentes como Modifier.scrollable e Modifier.transformable para ter um melhor comportamento com trackpads.

Essas mudanças melhoram o comportamento dos trackpads em componentes integrados, com a remoção de toques redundantes, um gesto inicial de arrastar e soltar mais intuitivo, seleção de clique duplo e clique triplo em campos de texto e menus de contexto no estilo desktop em campos de texto.

Para testar o comportamento do trackpad, existem novas APIs de teste com performTrackpadInputque permitem validar o comportamento de seus aplicativos ao serem usados ​​com um trackpad. Se você tiver detectores de gestos personalizados, valide o comportamento entre tipos de entrada, incluindo telas sensíveis ao toque, mouses, trackpads e canetas, e garanta suporte para rodas de rolagem do mouse e gestos do trackpad.

Antes Depois

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

Nós apresentamos HostDefaultProvider, LocalHostDefaultProvider, HostDefaultKeye ViewTreeHostDefaultKey para fornecer serviços em nível de host diretamente por meio do compose-runtime. Isso elimina a necessidade de as bibliotecas dependerem do 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 resolve os padrões do host.

Pré-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 o PreviewWrapperProvider interface e aplicando o novo @PreviewWrapper anotação, você pode facilmente injetar lógica personalizada, como aplicar um tema específico. A anotação pode ser aplicada a uma função anotada com @Composable e @Preview ou @MultiPreviewoferecendo uma solução genérica e fácil de usar que funciona com recursos de visualização e reduz significativamente o código repetitivo.

class ThemeWrapper: PreviewWrapper {

    @Composable

    override fun Wrap(content: @Composable (() -> Unit)) {

        JetsnackTheme {

            content()

        }

    }

}

@PreviewWrapperProvider(ThemeWrapper::class)

@Preview

@Composable

private fun ButtonPreview() {

    // JetsnackTheme in effect

    Button(onClick = {}) {

        Text(text = "Demo")

    }

}

Depreciações e remoções

  • Conforme anunciado no Compor postagem do blog 1.10estamos descontinuando Modifier.onFirstVisible(). Seu nome muitas vezes levava a conceitos errados, principalmente em layouts preguiçosos, onde era acionado várias vezes durante a rolagem. Recomendamos migrar para Modifier.onVisibilityChanged()que permite um rastreamento manual mais preciso dos estados de visibilidade adaptados aos requisitos específicos do seu caso de uso.
  • O ComposeFoundationFlags.isTextFieldDpadNavigationEnabled sinalizador foi removido porque a navegação no D-pad para TextFields agora está sempre habilitado por padrão. O novo comportamento garante que os eventos do D-pad de um gamepad ou controle remoto de TV movam primeiro o cursor na direção especificada. O foco pode passar para outro elemento somente quando o cursor atingir o final do texto.

Próximas APIs

Na próxima versão do Compose 1.12.0, o compileSdk será atualizado para compileSdk 37com o AGP 9 e todos os aplicativos e bibliotecas que dependem do Compose herdando esse requisito. Recomendamos manter-se atualizado com as versões mais recentes lançadas, pois o Compose pretende adotar imediatamente novas compileSdks para fornecer acesso aos recursos mais recentes do Android. Não deixe de conferir o documentação aqui para obter 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 @Experimentale estamos ansiosos para ouvir seus comentários enquanto você os explora em seus aplicativos. Observe que @Experimental As APIs são fornecidas para avaliação e feedback antecipados e podem sofrer alterações significativas ou serem removidas em versões futuras.

Estilos (Experimental)

Estamos introduzindo uma nova API experimental de base para estilo. A API Style é um novo paradigma para customização de elementos visuais de componentes, que tradicionalmente tem sido realizada com modificadores. Ele foi projetado para desbloquear uma personalização mais profunda e fácil, expondo um conjunto padrão de propriedades estilizáveis ​​com estilo simples baseado em estado e transições animadas. Com esta nova API, já vemos resultados promissores benefícios de desempenho. Planejamos adotar estilos em componentes de material assim que a API de estilo 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",
        )
    }
}

MediaQuery (Experimental)

O novo mediaQuery A API fornece uma maneira declarativa e de alto desempenho para adaptar sua UI ao seu ambiente. Ele abstrai a recuperação complexa de informações em condições simples dentro de um UiMediaScopegarantindo que a recomposição aconteça apenas quando necessário.

Com suporte para uma ampla variedade de sinais ambientais, desde recursos de dispositivos, como tipos de teclado e precisão do ponteiro, até estados contextuais, como tamanho e postura da janela, você pode criar experiências profundamente responsivas. O desempenho é integrado com derivedMediaQuery para lidar com atualizações de alta frequência, enquanto a capacidade de substituir escopos torna os testes e as visualizações perfeitos em todas as configurações de hardware.

Anteriormente, para obter acesso a determinadas propriedades do dispositivo, como se um dispositivo estivesse em modo de mesa – você precisaria escrever muitos clichês para fazer isso:

@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 UIMediaQueryvocê pode adicionar o mediaQuery sintaxe para consultar propriedades do dispositivo, como se um dispositivo estiver no modo de mesa:

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

Confira o documentação e registre quaisquer bugs aqui.

Grade (Experimental)

Grid é uma nova API poderosa para criar layouts bidimensionais complexos no Jetpack Compose. Enquanto Row e Column são ótimos para projetos lineares, Grid oferece o controle estrutural necessário para arquitetura em nível de tela e componentes complexos sem a sobrecarga de uma lista rolável.

Grid permite que você defina seu layout usando trilhas, lacunas e células, oferecendo opções de dimensionamento familiares como Dpporcentagens, tamanhos de conteúdo intrínseco 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 colocar itens de forma automática ou explícita em várias linhas e colunas para maior precisão. O melhor de tudo é que é altamente adaptável: você pode reconfigurar dinamicamente suas trilhas e extensões de grade para responder aos estados do dispositivo, como modo de mesa ou mudanças de orientação, garantindo que sua UI tenha uma ótima aparência em todos os formatos.

Confira o documentação e registre quaisquer bugs aqui.

FlexBox (Experimental)

FlexBox é um contêiner de layout projetado para UIs adaptáveis ​​e de alto desempenho. Ele gerencia o dimensionamento dos itens e a distribuição do espaço com base nas dimensões disponíveis do contêiner. Ele lida com tarefas complexas como empacotamento (wrap) e alinhamento multieixo de itens (justifyContent, alignItems, alignContent). Permite que os itens cresçam (grow) ou encolher (shrink) para encher o recipiente.

@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 o documentação e registre quaisquer bugs aqui.

Nova implementação SlotTable (Experimental)

Introduzimos uma nova implementação do SlotTableque está desabilitado 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. Esta nova implementação foi projetada para melhorar o desempenho, principalmente em relação a edições aleatórias.

Para experimentar o novo SlotTablehabilitar ComposeRuntimeFlags.isLinkBufferComposerEnabled.

Comece a codificar hoje!

Com tantas novas APIs interessantes no Jetpack Compose e muitas outras chegando, nunca foi um momento melhor para migrar para o Jetpack Compose. Como sempre, valorizamos seus comentários e solicitações de recursos (especialmente em @Experimental recursos que ainda estão em desenvolvimento) – arquive-os aqui. Feliz composição!

Deixe um Comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *