Modificadores do Compose

Mantenha tudo organizado com as coleções Salve e categorize o conteúdo com base nas suas preferências.

Os modificadores permitem decorar ou aumentar as funções que podem ser compostas. Com os modificadores, é possível fazer o seguinte:

  • Mudar o tamanho, o layout, o comportamento e a aparência do elemento
  • Adicionar informações, como rótulos de acessibilidade
  • Processar a entrada do usuário
  • Adicionar interações de nível superior, como tornar um elemento clicável, rolável, arrastável ou redimensionável

Modificadores são objetos Kotlin padrão. Crie um modificador chamando uma das funções de classe Modifier.

import androidx.compose.ui.Modifier

@Composable
private fun Greeting(name: String) {
  Column(modifier = Modifier.padding(24.dp)) {
    Text(text = "Hello,")
    Text(text = name)
  }
}

Duas linhas de texto em um plano de fundo colorido, com padding ao redor do texto.

É possível encadear essas funções para fazer a composição delas:

@Composable
private fun Greeting(name: String) {
  Column(modifier = Modifier
    .padding(24.dp)
    .fillMaxWidth()
  ) {
    Text(text = "Hello,")
    Text(text = name)
  }
}

O plano de fundo colorido por trás do texto agora se estende para preencher toda a largura do dispositivo.

Observe diferentes funções de modificador sendo usadas juntas no código acima.

  • padding cria um espaço ao redor de um elemento.
  • fillMaxWidth faz a função que pode ser composta preencher a largura máxima atribuída a ela pelo elemento pai.

É uma prática recomendada que todos os elementos que podem ser compostos aceitem um parâmetro modifier e transmitam esse modificador ao primeiro filho que emite a IU. Isso torna seu código mais reutilizável e deixa o comportamento dele mais previsível e intuitivo. Para mais informações, consulte as diretrizes da API Compose: Os elementos aceitam e respeitam um parâmetro modificador.

A ordem dos modificadores é importante

A ordem das funções modificadoras é importante. Como cada função realiza mudanças no Modifier retornado pela função anterior, a sequência afeta o resultado final. Veja um exemplo disso:

@Composable
fun ArtistCard(/*...*/) {
    val padding = 16.dp
    Column(
        Modifier
            .clickable(onClick = onClick)
            .padding(padding)
            .fillMaxWidth()
    ) {
        // rest of the implementation
    }
}

Toda a área, incluindo o preenchimento ao redor das bordas, responde aos cliques

No código acima, a área inteira é clicável, incluindo o padding ao redor dela, porque o modificador padding foi aplicado depois do modificador clickable. Se a ordem dos modificadores for invertida, o espaço adicionado por padding não reagirá à entrada do usuário:

@Composable
fun ArtistCard(/*...*/) {
    val padding = 16.dp
    Column(
        Modifier
            .padding(padding)
            .clickable(onClick = onClick)
            .fillMaxWidth()
    ) {
        // rest of the implementation
    }
}

O preenchimento ao redor da borda do layout não responde mais aos cliques

Modificadores integrados

O Jetpack Compose oferece uma lista de modificadores integrados para ajudar você a decorar ou aumentar uma função que pode ser composta. Veja alguns modificadores comuns que você vai usar para ajustar seus layouts.

padding e size

Por padrão, os layouts fornecidos no Compose unem os filhos. No entanto, é possível definir um tamanho usando o modificador size:

@Composable
fun ArtistCard(/*...*/) {
    Row(
        modifier = Modifier.size(width = 400.dp, height = 100.dp)
    ) {
        Image(/*...*/)
        Column { /*...*/ }
    }
}

O tamanho especificado pode não ser respeitado caso ele não atenda às restrições provenientes do pai do layout. Caso você precise que o tamanho do elemento de composição seja corrigido, independentemente das restrições de entrada, use o modificador requiredSize:

@Composable
fun ArtistCard(/*...*/) {
    Row(
        modifier = Modifier.size(width = 400.dp, height = 100.dp)
    ) {
        Image(
            /*...*/
            modifier = Modifier.requiredSize(150.dp)
        )
        Column { /*...*/ }
    }
}

A imagem filha é maior do que as restrições do pai

Nesse exemplo, mesmo com a height do elemento pai definida como 100.dp, a altura da Image será 150.dp, já que o modificador requiredSize tem precedência.

Caso você queira que um layout filho preencha toda a altura disponibilizada pelo pai, adicione o modificador fillMaxHeight. O Compose também oferece fillMaxSize e fillMaxWidth:

@Composable
fun ArtistCard(/*...*/) {
    Row(
        modifier = Modifier.size(width = 400.dp, height = 100.dp)
    ) {
        Image(
            /*...*/
            modifier = Modifier.fillMaxHeight()
        )
        Column { /*...*/ }
    }
}

A altura da imagem é tão grande quanto a do pai

Para adicionar padding ao redor de um elemento, defina um modificador padding.

Caso queira adicionar padding acima da linha de base do texto, de modo a estabelecer uma distância específica do topo do layout até a linha de base, use o modificador paddingFromBaseline:

@Composable
fun ArtistCard(artist: Artist) {
    Row(/*...*/) {
        Column {
            Text(
                text = artist.name,
                modifier = Modifier.paddingFromBaseline(top = 50.dp)
            )
            Text(artist.lastSeenOnline)
        }
    }
}

Texto com padding na parte superior

Offset

Para posicionar um layout em relação à posição original, adicione o modificador offset e defina o deslocamento no eixo x e y. Os deslocamentos podem ser positivos e não positivos. A diferença entre padding e offset é que adicionar um offset a uma função não muda as medidas dela:

@Composable
fun ArtistCard(artist: Artist) {
    Row(/*...*/) {
        Column {
            Text(artist.name)
            Text(
                text = artist.lastSeenOnline,
                modifier = Modifier.offset(x = 4.dp)
            )
        }
    }
}

Texto deslocado para o lado direito do contêiner pai

O modificador offset é aplicado horizontalmente, de acordo com a direção do layout. Em um contexto de sentido da esquerda para a direita, um offset positivo desloca o elemento para a direita. Já em um contexto de sentido da direita para esquerda, o elemento é deslocado para a esquerda. Caso seja necessário definir um deslocamento sem considerar a direção do layout, analise o modificador absoluteOffset, em que um valor de deslocamento positivo sempre desloca o elemento para a direita.

Segurança de tipo no Compose

No Compose, há modificadores que só funcionam quando aplicados a filhos de determinados elementos que podem ser compostos. Por exemplo, se você quiser deixar um filho do tamanho da Box mãe sem afetar o tamanho da Box, use o modificador matchParentSize.

O Compose aplica essa segurança de tipo usando escopos personalizados. Por exemplo, matchParentSize está disponível apenas em BoxScope. Portanto, ele só pode ser usado quando o filho for usado em uma Box.

Os modificadores com escopo informam o pai sobre algumas informações que ele precisa saber sobre o elemento filho. Eles também costumam ser chamados de modificadores de dados pai. Os componentes internos são diferentes dos modificadores de uso geral, mas do ponto de vista do uso, essas diferenças não importam.

matchParentSize no elemento Box

Como mencionado acima, se você quiser que um layout filho tenha o mesmo tamanho de uma Box mãe sem afetar o tamanho da Box, use o modificador matchParentSize.

O matchParentSize só está disponível em um escopo de Box, o que significa que ele se aplica apenas a filhos diretos das funções Box que podem ser compostas.

No exemplo abaixo, o Spacer filho tem o tamanho da Box mãe, que, por sua vez, assume o tamanho dos filhos maiores, ArtistCard neste caso.

@Composable
fun MatchParentSizeComposable() {
    Box {
        Spacer(Modifier.matchParentSize().background(Color.LightGray))
        ArtistCard()
    }
}

Plano de fundo cinza como preenchimento do contêiner

Se fillMaxSize fosse usado em vez de matchParentSize, o Spacer ocuparia todo o espaço disponibilizado para o pai, fazendo com que o pai fosse expandido e preenchesse todo o espaço disponível.

Plano de fundo cinza como preenchimento da tela

weight em Row e Column

Conforme abordado na seção anterior sobre preenchimento e tamanho, por padrão, o tamanho de uma função que pode ser composta é definido pelo conteúdo que ela agrupa. Você pode definir um tamanho que pode ser composto como flexível no pai usando o modificador weight, disponível apenas em RowScope, e ColumnScope.

Vamos considerar uma Row contendo duas Box que podem ser compostas. A primeira caixa recebe o dobro de weight da segunda, portanto, duas vezes a largura. Como a Row tem 210.dp de largura, a primeira Box tem 140.dp de largura e a segunda tem 70.dp:

@Composable
fun ArtistCard(/*...*/) {
    Row(
        modifier = Modifier.fillMaxWidth()
    ) {
        Image(
            /*...*/
            modifier = Modifier.weight(2f)
        )
        Column(
            modifier = Modifier.weight(1f)
        ) {
            /*...*/
        }
    }
}

A largura da imagem é o dobro da largura do texto

Saiba mais

Fornecemos uma lista completa de modificadores com os parâmetros e escopos deles.