No Compose, é possível encadear vários modificadores para mudar a aparência e a sensação de um elemento combinável. Essas cadeias de modificadores podem afetar as restrições transmitidas aos elementos combináveis, que definem os limites de largura e altura.
Esta página descreve como os modificadores encadeados afetam as restrições e, por sua vez, a medição e o posicionamento dos elementos combináveis.
Modificadores na árvore da interface
Para entender como os modificadores influenciam uns aos outros, visualize como eles aparecem na árvore da interface, que é gerada durante a fase de composição. Para mais informações, consulte a seção Composição.
Na árvore da interface, você pode visualizar os modificadores como nós do wrapper para os nós de layout:
Adicionar mais de um modificador a um elemento combinável cria uma cadeia de modificadores. Ao
encadear vários modificadores, cada nó modificador encapsula o restante da cadeia
e o nó de layout (link em inglês). Por exemplo, quando você encadeia um clip
e um
modificador size
, o nó modificador clip
une o nó modificador size
,
que, em seguida, une o nó de layout Image
.
Na fase de layout, o algoritmo que percorre a árvore permanece o mesmo, mas cada nó modificador também é visitado. Dessa forma, um modificador pode mudar os requisitos de tamanho e o posicionamento do modificador ou do nó de layout que ele envolve.
Conforme mostrado na Figura 2, a implementação dos elementos combináveis Image
e Text
consiste em uma cadeia de modificadores que envolvem um único nó de layout. As
implementações de Row
e Column
são simplesmente nós de layout que descrevem como
dispor os filhos.
Para resumir:
- Os modificadores unem um único nó de layout ou modificador.
- Os nós do layout podem dispor vários nós filhos.
As seções abaixo descrevem como usar esse modelo mental para entender o encadeamento do modificador e como ele influencia o tamanho dos elementos combináveis.
Restrições na fase de layout
A fase de layout segue um algoritmo de três etapas para encontrar a largura, a altura e as coordenadas x, y de cada nó de layout:
- Medir filhos: um nó mede os filhos, se houver.
- Decidir o próprio tamanho: com base nessas medidas, um nó decide seu próprio tamanho.
- Colocar filhos: cada nó filho é colocado em relação à própria posição de um nó.
Constraints
ajuda a encontrar os tamanhos corretos dos nós durante as duas primeiras
etapas do algoritmo. As restrições definem os limites mínimo e máximo para a largura e a altura de um nó. Quando o nó decide sobre o próprio tamanho, o tamanho medido
dele fica dentro desse intervalo.
Tipos de restrições
Uma restrição pode ser uma das seguintes:
- Delimitado: o nó tem largura e altura máxima e mínima.
- Ilimitado: o nó não está restrito a nenhum tamanho. Os limites máximos de largura e altura são definidos como infinito.
- Exata: o nó precisa seguir um requisito de tamanho exato. Os limites mínimo e máximo são definidos com o mesmo valor.
- Combinação: o nó segue uma combinação dos tipos de restrição acima. Por exemplo, uma restrição pode limitar a largura, permitindo uma altura máxima ilimitada, ou definir uma largura exata, mas fornecer uma altura limitada.
A próxima seção descreve como essas restrições são transmitidas de um pai para um filho.
Como as restrições são transmitidas do pai para o filho
Durante a primeira etapa do algoritmo descrito em Restrições na fase de layout, as restrições são transmitidas do pai para o filho na árvore da interface.
Quando um nó pai mede os filhos, ele fornece essas restrições a cada filho para informar o tamanho máximo ou pequeno que eles podem ter. Então, quando ele decide o próprio tamanho, ele também segue as restrições transmitidas pelos próprios pais.
Em um nível alto, o algoritmo funciona da seguinte maneira:
- Para decidir o tamanho que realmente quer ocupar, o nó raiz na árvore da interface mede os filhos e encaminha as mesmas restrições ao primeiro filho.
- Se o filho for um modificador que não afeta a medição, ele encaminhará as restrições para o próximo modificador. As restrições são transmitidas para a cadeia de modificadores no estado em que se encontram, a menos que um modificador que afete a medição seja alcançado. As restrições são redimensionadas de acordo com o tamanho.
- Quando um nó é alcançado e não tem filhos (conhecido como "nó de folha"), ele decide o tamanho com base nas restrições transmitidas e retorna esse tamanho resolvido ao pai.
- O pai adapta as restrições com base nas medidas desse filho e chama o próximo filho com essas restrições ajustadas.
- Depois que todos os filhos de um pai são medidos, o nó pai decide o próprio tamanho e o comunica ao pai.
- Dessa forma, toda a árvore é atravessada em profundidade primeiro. Por fim, todos os nós decidiram os tamanhos, e a etapa de medição foi concluída.
Para ver um exemplo detalhado, assista ao vídeo Restrições e ordem dos modificadores.
Modificadores que afetam restrições
Você aprendeu na seção anterior que alguns modificadores podem afetar o tamanho da restrição. As seções abaixo descrevem modificadores específicos que afetam as restrições.
Modificador size
O modificador size
declara o tamanho preferido do conteúdo.
Por exemplo, a árvore de interface abaixo precisa ser renderizada em um contêiner de 300dp
por 200dp
. As restrições são limitadas, permitindo larguras entre 100dp
e
300dp
e alturas entre 100dp
e 200dp
:
O modificador size
adapta as restrições recebidas para corresponder ao valor transmitido a ele.
Neste exemplo, o valor é 150dp
:
Se a largura e a altura forem menores que o menor limite de restrição ou maiores que o maior limite, o modificador vai corresponder às restrições transmitidas da melhor forma possível, respeitando as restrições transmitidas:
O encadeamento de vários modificadores size
não funciona. O primeiro modificador size
define as restrições mínima e máxima como um valor fixo. Mesmo que
o segundo modificador de tamanho solicite um tamanho menor ou maior, ele ainda precisa
seguir os limites exatos transmitidos para que ele não substitua esses valores:
Modificador requiredSize
Use o modificador requiredSize
em vez de size
se precisar que
o nó modifique as restrições de entrada. O modificador requiredSize
substitui
as restrições de entrada e transmite o tamanho especificado como limites exatos.
Quando o tamanho é passado para a árvore, o nó filho é centralizado no espaço disponível:
Modificadores: width
e height
O modificador size
adapta a largura e a altura das restrições. Com
o modificador width
, você pode definir uma largura fixa, mas não definir a altura.
Da mesma forma, com o modificador height
, você pode definir uma altura fixa, mas deixar a
largura indeciso:
Modificador sizeIn
O modificador sizeIn
permite definir restrições mínimas e máximas
exatas para largura e altura. Use o modificador sizeIn
se precisar de um controle refinado
sobre as restrições.
Exemplos
Esta seção mostra e explica a saída de vários snippets de código com modificadores encadeados.
Image( painterResource(R.drawable.hero), contentDescription = null, Modifier .fillMaxSize() .size(50.dp) )
O snippet abaixo produz a seguinte saída:
- O modificador
fillMaxSize
muda as restrições para definir a largura e a altura mínimas como o valor máximo:300dp
de largura e200dp
de altura. - Mesmo que o modificador
size
queira usar um tamanho de50dp
, ele ainda precisa seguir as restrições mínimas recebidas. Portanto, o modificadorsize
também gerará os limites de restrição exatos de300
por200
, ignorando efetivamente o valor fornecido no modificadorsize
. - O
Image
segue esses limites e informa um tamanho de300
por200
, que é transmitido até o topo da árvore.
Image( painterResource(R.drawable.hero), contentDescription = null, Modifier .fillMaxSize() .wrapContentSize() .size(50.dp) )
O snippet abaixo produz a seguinte saída:
- O modificador
fillMaxSize
adapta as restrições para definir a largura e a altura mínimas como o valor máximo:300dp
de largura e200dp
de altura. - O modificador
wrapContentSize
redefine as restrições mínimas. Assim, emborafillMaxSize
tenha resultado em restrições fixas,wrapContentSize
a redefine de volta para restrições limitadas. O nó a seguir agora pode ocupar todo o espaço de novo ou ser menor que ele. - O modificador
size
define as restrições para os limites mínimo e máximo de50
. - O
Image
é resolvido para um tamanho de50
por50
, e o modificadorsize
encaminha isso. - O modificador
wrapContentSize
tem uma propriedade especial. Ele recebe o filho e o coloca no centro dos limites mínimos disponíveis que foram transmitidos a ele. O tamanho que ela comunica aos pais é, portanto, igual aos limites mínimos transmitidos a ele.
Ao combinar apenas três modificadores, você pode definir um tamanho para o elemento combinável e o centralizar no pai.
Image( painterResource(R.drawable.hero), contentDescription = null, Modifier .clip(CircleShape) .padding(10.dp) .size(100.dp) )
O snippet abaixo produz a seguinte saída:
- O modificador
clip
não muda as restrições.- O modificador
padding
diminui as restrições máximas. - O modificador
size
define todas as restrições como100dp
. - O
Image
segue essas restrições e informa um tamanho de100
por100dp
. - O modificador
padding
adiciona10dp
a todos os tamanhos, aumentando a largura e altura informadas em20dp
. - Agora, na fase de exibição, o modificador
clip
atua em uma tela de120
por120dp
. Portanto, ela cria uma máscara circular desse tamanho. - Em seguida, o modificador
padding
insere o próprio conteúdo em10dp
em todos os tamanhos, para diminuir o tamanho da tela para100
em100dp
. - O
Image
é desenhado nessa tela. A imagem é recortada com base no círculo original de120dp
, de modo que a saída é um resultado não redondo.
- O modificador