Há três maneiras de adotar estilos no app:
- Use diretamente em componentes atuais que expõem um
Styleparâmetro. - Aplique um estilo com
Modifier.styleableem elementos combináveis de layout que não aceitam umStyleparâmetro. - No seu próprio sistema de design personalizado, use
Modifier.styleable{}e exponha um parâmetro de estilo nos seus próprios componentes.
Propriedades disponíveis em estilos
Os estilos oferecem suporte a muitas das mesmas propriedades que os modificadores. No entanto, nem tudo que é um modificador pode ser replicado com um estilo. Você ainda precisa de modificadores para determinados comportamentos, como interações, desenho personalizado ou empilhamento de propriedades.
| Agrupamento | Propriedades | Herdadas por filhos |
|---|---|---|
| Layout e dimensionamento | ||
| Padding de conteúdo (interno) | - contentPadding(all: Dp)- contentPadding(horizontal: Dp, vertical: Dp)- contentPadding(start: Dp, top: Dp, end: Dp, bottom: Dp)- contentPaddingHorizontal(value: Dp) / contentPaddingVertical(value: Dp)- contentPaddingStart(value: Dp) / contentPaddingTop(value: Dp) / contentPaddingEnd(value: Dp) / contentPaddingBottom(value: Dp) |
Não |
| Padding externo (externo) | - externalPadding(all: Dp)- externalPadding(horizontal: Dp, vertical: Dp)- externalPadding(start: Dp, top: Dp, end: Dp, bottom: Dp)- externalPaddingHorizontal(value: Dp) / externalPaddingVertical(value: Dp)- externalPaddingStart(value: Dp) / externalPaddingTop(value: Dp) / externalPaddingEnd(value: Dp) / externalPaddingBottom(value: Dp) |
Não |
| Dimensões | fillWidth()/fillHeight()/fillSize() e width, height e size (oferece suporte a frações Dp, DpSize ou Float). |
Não |
| Posicionamento | Deslocamentos left/top/right/bottom. |
Não |
| Aparência visual | ||
| Carrega | background e foreground (oferece suporte a Color ou Brush). |
Não |
| Bordas | borderWidth, borderColor e borderBrush. |
Não |
| Forma | shape |
Não, mas usado em conjunto com outras propriedades. clip e border usam essa forma definida. |
| Sombras | dropShadow, innerShadow |
Não |
| Transformações | ||
| Movimento espacial da camada de gráficos | translationX, translationY, scaleX/scaleY, rotationX/rotationY/rotationZ |
Não |
| Controle | alpha, zIndex (ordem de empilhamento) e transformOrigin (ponto de ancoragem) |
Não |
| Tipografia | ||
| Estilo | textStyle, fontSize, fontWeight, fontStyle e fontFamily |
Sim |
| Coloração | contentColor e contentBrush. Isso também é usado para estilizar ícones. |
Sim |
| Parágrafo | lineHeight, letterSpacing, textAlign, textDirection, lineBreak e hyphens. |
Sim |
| Decoração | textDecoration, textIndent e baselineShift. |
Sim |
Usar estilos diretamente em componentes com parâmetros de estilo
Os componentes que expõem um parâmetro Style permitem definir o estilo deles:
BaseButton( onClick = { }, style = { } ) { BaseText("Click me") }
Na lambda de estilo, você pode definir várias propriedades, como externalPadding ou background:
BaseButton( onClick = { }, style = { background(Color.Blue) } ) { BaseText("Click me") }
Para conferir a lista completa de propriedades compatíveis, consulte Propriedades disponíveis em estilos.
Aplicar estilos usando modificadores para componentes sem parâmetro atual
Para componentes que não têm um parâmetro de estilo integrado, ainda é possível aplicar estilos com o modificador styleable. Essa abordagem também é útil ao desenvolver seus próprios componentes personalizados.
Row( modifier = Modifier.styleable { } ) { BaseText("Content") }
Semelhante ao parâmetro style, você pode incluir propriedades como background, contentPadding ou externalPadding dentro da lambda.
Row( modifier = Modifier.styleable { background(Color.Blue) } ) { BaseText("Content") }
Vários modificadores Modifier.styleable encadeados são aditivos com propriedades não herdadas no elemento combinável aplicado, comportando-se de maneira semelhante a vários modificadores que definem as mesmas propriedades. Para propriedades herdadas, elas são substituídas, e o último modificador styleable na cadeia define os valores.
Ao usar Modifier.styleable, talvez você também queira criar e fornecer um StyleState para ser usado com o modificador para aplicar estilos baseados no estado. Para mais
detalhes, consulte Estado e animações com
estilos.
Definir um estilo independente
Você pode definir um estilo independente para fins de reutilização:
val style = Style { background(Color.Blue) }
Em seguida, transmita esse estilo definido para o parâmetro de estilo de um elemento combinável ou com Modifier.styleable. Ao usar Modifier.styleable, também é necessário criar um objeto StyleState. StyleState é abordado em detalhes na documentação Estado e
animações com estilos.
O exemplo a seguir mostra como aplicar um estilo diretamente pelos parâmetros integrados de um componente ou por um Modifier.styleable:
val style = Style { background(Color.Blue) } // built in parameter BaseButton(onClick = { }, style = style) { BaseText("Button") } // modifier styleable val styleState = remember { MutableStyleState(null) } Column( Modifier.styleable(styleState, style) ) { BaseText("Column content") }
Também é possível transmitir esse estilo para vários componentes:
val style = Style { background(Color.Blue) } // built in parameter BaseButton(onClick = { }, style = style) { BaseText("Button") } BaseText("Different text that uses the same style parameter", style = style) // modifier styleable val columnStyleState = remember { MutableStyleState(null) } Column( Modifier.styleable(columnStyleState, style) ) { BaseText("Column") } val rowStyleState = remember { MutableStyleState(null) } Row( Modifier.styleable(rowStyleState, style) ) { BaseText("Row") }
Adicionar várias propriedades de estilo
É possível adicionar várias propriedades de estilo definindo propriedades diferentes em cada linha:
BaseButton( onClick = { }, style = { background(Color.Blue) contentPaddingStart(16.dp) } ) { BaseText("Button") }
As propriedades em estilos não são aditivas, ao contrário do estilo baseado em modificadores. Os estilos usam o último valor definido na lista de propriedades em um bloco de estilo. No exemplo a seguir, com o plano de fundo definido duas vezes, o TealColor é o plano de fundo aplicado. Para o padding, contentPaddingTop substitui o padding superior definido por contentPadding e não combina os valores.
BaseButton( style = { background(Color.Red) // Background of Red is now overridden with TealColor instead background(TealColor) // All directions of padding are set to 64.dp (top, start, end, bottom) contentPadding(64.dp) // Top padding is now set to 16.dp, all other paddings remain at 64.dp contentPaddingTop(16.dp) }, onClick = { // } ) { BaseText("Click me!") }
contentPadding.Mesclar vários objetos de estilo
É possível criar vários objetos de estilo e transmiti-los para o parâmetro de estilo do elemento combinável.
val style1 = Style { background(TealColor) } val style2 = Style { contentPaddingTop(16.dp) } BaseButton( style = style1 then style2, onClick = { }, ) { BaseText("Click me!") }
contentPaddingTop definidos.Quando vários estilos especificam a mesma propriedade, a última propriedade definida é escolhida. Como as propriedades não são aditivas em estilos, o último
padding transmitido substitui o contentPaddingHorizontal definido pelo contentPadding inicial. Além disso, a última cor de plano de fundo substitui a cor de plano de fundo definida pelo estilo inicial transmitido.
val style1 = Style { background(Color.Red) contentPadding(32.dp) } val style2 = Style { contentPaddingHorizontal(8.dp) background(Color.LightGray) } BaseButton( style = style1 then style2, onClick = { }, ) { BaseText("Click me!") }
Nesse caso, o estilo aplicado tem um plano de fundo cinza claro e um padding de 32.dp, exceto o padding esquerdo e direito, que tem um valor de 8.dp.
contentPadding substituído por estilos diferentes.Herança de estilo
Determinadas propriedades de estilo, como contentColor e propriedades relacionadas ao estilo de texto, são propagadas para os elementos combináveis filhos. Um estilo definido em um elemento combinável filho substitui o estilo principal herdado para esse filho específico.
Style, styleable e diretos.| Prioridade | Método | Efeito |
|---|---|---|
| 1 (máxima) | Argumentos diretos em um elemento combinável | Substitui tudo. Por exemplo, Text(color = Color.Red) |
| 2 | Parâmetro de estilo | Substituições de estilo local Text(style = Style { contentColor(Color.Red)} |
| 3 | Cadeia de modificadores | Modifier.styleable{ contentColor(Color.Red) no próprio componente. |
| 4 (mínima) | Estilos principais | Para propriedades que podem ser herdadas (tipografia/cor) transmitidas do pai. |
Estilo principal
É possível definir propriedades de texto (como contentColor) do elemento combinável principal, e elas são propagadas para todos os elementos combináveis Text filhos.
val styleState = remember { MutableStyleState(null) } Column( modifier = Modifier.styleable(styleState) { background(Color.LightGray) val blue = Color(0xFF4285F4) val purple = Color(0xFFA250EA) val colors = listOf(blue, purple) contentBrush(Brush.linearGradient(colors)) }, ) { BaseText("Children inherit", style = { width(60.dp) }) BaseText("certain properties") BaseText("from their parents") }
Substituição de propriedades filhas
Também é possível definir o estilo em um elemento combinável Text específico. Se o elemento combinável principal tiver um estilo definido, o estilo definido no elemento combinável filho vai substituir o estilo do elemento combinável principal.
val styleState = remember { MutableStyleState(null) } Column( modifier = Modifier.styleable(styleState) { background(Color.LightGray) val blue = Color(0xFF4285F4) val purple = Color(0xFFA250EA) val colors = listOf(blue, purple) contentBrush(Brush.linearGradient(colors)) }, ) { BaseText("Children can ", style = { contentBrush(Brush.linearGradient(listOf(Color.Red, Color.Blue))) }) BaseText("override properties") BaseText("set by their parents") }
Implementar propriedades de estilo personalizadas
É possível criar propriedades personalizadas que são mapeadas para definições de estilo atuais usando funções de extensão no StyleScope, conforme mostrado no exemplo a seguir:
fun StyleScope.outlinedBackground(color: Color) { border(1.dp, color) background(color) }
Aplique essa nova propriedade em uma definição de estilo:
val customExtensionStyle = Style { outlinedBackground(Color.Blue) }
A criação de novas propriedades estilizadas não é compatível. Se o caso de uso exigir esse suporte, envie uma solicitação de recurso.
Ler valores CompositionLocal
É um padrão comum armazenar tokens do sistema de design em um CompositionLocal para acessar as variáveis sem precisar transmiti-las como parâmetros. Os estilos podem acessar CompositionLocals para recuperar valores em todo o sistema dentro de um estilo:
val buttonStyle = Style { contentPadding(12.dp) shape(RoundedCornerShape(50)) background(Brush.verticalGradient(LocalCustomColors.currentValue.background)) }