O que e Modifier em Kotlin?
Modifier e o mecanismo do Jetpack Compose para decorar, configurar e modificar componentes de UI. Ele controla aparencia (tamanho, padding, cor de fundo), comportamento (clique, scroll, foco) e layout (alinhamento, preenchimento, posicionamento) de qualquer Composable.
Em vez de definir atributos em XML como no sistema antigo de Views, voce encadeia chamadas de Modifier em uma sintaxe fluente e expressiva. A ordem das chamadas importa e afeta o resultado visual.
Sintaxe basica
import androidx.compose.foundation.layout.*
import androidx.compose.material3.*
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
@Composable
fun CartaoSimples() {
Card(
modifier = Modifier
.fillMaxWidth()
.padding(16.dp)
) {
Text(
text = "Conteudo do cartao",
modifier = Modifier.padding(24.dp)
)
}
}
O Modifier comeca como um objeto companheiro (singleton) e cada chamada retorna um novo Modifier com a modificacao aplicada. A cadeia e imutavel: cada passo cria um novo objeto.
A ordem importa
A ordem em que voce encadeia modifiers afeta diretamente o resultado:
// Padding ANTES do background: espaco transparente ao redor do fundo
@Composable
fun ExemploA() {
Box(
modifier = Modifier
.padding(16.dp)
.background(Color.Blue)
.size(100.dp)
)
}
// Background ANTES do padding: fundo preenche o espaco do padding
@Composable
fun ExemploB() {
Box(
modifier = Modifier
.background(Color.Blue)
.padding(16.dp)
.size(100.dp)
)
}
Pense nos modifiers como camadas aplicadas de fora para dentro. O primeiro modifier na cadeia e a camada mais externa.
Modifiers de tamanho
@Composable
fun ExemplosTamanho() {
// Tamanho fixo
Box(modifier = Modifier.size(100.dp))
// Largura e altura separadas
Box(modifier = Modifier.width(200.dp).height(50.dp))
// Preencher todo o espaco disponivel
Box(modifier = Modifier.fillMaxSize())
// Preencher apenas largura
Box(modifier = Modifier.fillMaxWidth())
// Preencher uma fracao
Box(modifier = Modifier.fillMaxWidth(0.5f)) // 50% da largura
// Tamanho minimo e maximo
Box(modifier = Modifier.widthIn(min = 100.dp, max = 300.dp))
// Tamanho baseado em aspecto
Box(modifier = Modifier.aspectRatio(16f / 9f))
}
Modifiers de aparencia
@Composable
fun ExemplosAparencia() {
Box(
modifier = Modifier
.size(200.dp)
.background(
color = Color.Blue,
shape = RoundedCornerShape(16.dp)
)
.border(
width = 2.dp,
color = Color.DarkGray,
shape = RoundedCornerShape(16.dp)
)
.shadow(
elevation = 8.dp,
shape = RoundedCornerShape(16.dp)
)
.alpha(0.9f)
)
}
Modifiers de interacao
@Composable
fun ExemplosInteracao() {
var clicado by remember { mutableStateOf(false) }
Box(
modifier = Modifier
.clickable { clicado = !clicado }
.combinedClickable(
onClick = { /* clique simples */ },
onLongClick = { /* clique longo */ },
onDoubleClick = { /* clique duplo */ }
)
)
// Scroll
Column(
modifier = Modifier.verticalScroll(rememberScrollState())
) {
// Conteudo scrollavel
}
// Arrastar
Box(
modifier = Modifier.draggable(
orientation = Orientation.Horizontal,
state = rememberDraggableState { delta ->
// Processar delta do arrasto
}
)
)
}
Criando Modifiers customizados
Voce pode criar extension functions em Modifier para reutilizar combinacoes:
fun Modifier.cartaoPadrao(): Modifier = this
.fillMaxWidth()
.padding(horizontal = 16.dp, vertical = 8.dp)
.shadow(4.dp, RoundedCornerShape(12.dp))
.background(Color.White, RoundedCornerShape(12.dp))
.padding(16.dp)
@Composable
fun MeuCartao(titulo: String) {
Column(modifier = Modifier.cartaoPadrao()) {
Text(text = titulo)
}
}
Para modifiers que dependem de estado do Compose, use composed:
fun Modifier.shimmerEffect(): Modifier = composed {
val transition = rememberInfiniteTransition()
val alpha by transition.animateFloat(
initialValue = 0.2f,
targetValue = 1f,
animationSpec = infiniteRepeatable(
animation = tween(1000),
repeatMode = RepeatMode.Reverse
)
)
this.alpha(alpha)
}
Modifier como parametro
O padrao recomendado e aceitar Modifier como parametro em Composables reutilizaveis:
@Composable
fun BotaoCustom(
texto: String,
onClick: () -> Unit,
modifier: Modifier = Modifier // Valor padrao: Modifier vazio
) {
Button(
onClick = onClick,
modifier = modifier
.height(48.dp)
.fillMaxWidth()
) {
Text(text = texto)
}
}
// Uso: o chamador pode adicionar modifiers extras
@Composable
fun Tela() {
BotaoCustom(
texto = "Salvar",
onClick = { /* ... */ },
modifier = Modifier.padding(16.dp) // Adicionado pelo chamador
)
}
O parametro modifier deve ser o primeiro parametro opcional e ter Modifier (vazio) como valor padrao. Isso segue as convencoes da API do Compose.
Modifier.then para composicao condicional
@Composable
fun ComponenteCondicional(habilitado: Boolean) {
val modifierBase = Modifier.fillMaxWidth().padding(16.dp)
val modifierFinal = if (habilitado) {
modifierBase.then(Modifier.clickable { /* acao */ })
} else {
modifierBase.then(Modifier.alpha(0.5f))
}
Box(modifier = modifierFinal) {
Text("Conteudo")
}
}
Quando usar Modifier
- Sempre: praticamente todo Composable aceita e deveria aceitar um parametro Modifier. E a forma padrao de configurar aparencia e comportamento.
- Componentes reutilizaveis: sempre aceite
modifiercomo parametro para permitir customizacao pelo chamador. - Estilizacao consistente: crie extension functions de Modifier para padroes visuais reutilizaveis.
- Layout: Modifiers controlam como componentes se posicionam e ocupam espaco.
Erros comuns
Ignorar a ordem dos modifiers:
paddingantes debackgrounde diferente debackgroundantes depadding. Sempre teste visualmente com@Preview.Nao aceitar Modifier como parametro: componentes que nao aceitam Modifier nao podem ser estilizados externamente, reduzindo a reutilizacao.
Usar Modifier.size fixo em excesso: tamanhos fixos nao se adaptam a diferentes telas. Prefira
fillMaxWidthcom padding ouwidthIncom limites.Criar modifiers dentro de lambdas de recomposicao: se um modifier e criado com
composedouremember, certifique-se de que nao esta sendo recriado desnecessariamente.Nao encadear com o modifier recebido: quando voce recebe
modifiercomo parametro, aplique-o no elemento raiz antes de adicionar seus proprios modifiers.
Termos relacionados
- Composable: funcao anotada com
@Composableque descreve UI e aceita Modifiers. - State: estado reativo que pode ser usado em conjunto com modifiers condicionais.
- Layout: sistema de posicionamento do Compose onde Modifiers influenciam tamanho e posicao.
- padding/size/fillMaxWidth: funcoes de extensao de Modifier para configurar dimensoes.
- clickable: modifier de interacao que torna componentes clicaveis.
- Recomposicao: processo que reaplica modifiers quando o estado muda.
Modifier e o canivete suico do Jetpack Compose. Dominar a encadeamento de modifiers, entender a importancia da ordem e criar modifiers customizados reutilizaveis sao habilidades fundamentais para construir interfaces bonitas e funcionais em Kotlin.