Restrições e ordem dos modificadores

No Compose, é possível encadear vários modificadores para mudar a aparência e de um elemento combinável. Essas cadeias de modificadores podem afetar as restrições transmitidas a elementos combináveis, que definem limites de largura e altura.

Esta página descreve como os modificadores encadeados afetam as restrições e, por sua vez, medição e posicionamento de elementos combináveis.

Modificadores na árvore da interface

Para entender como os modificadores influenciam uns aos outros, é útil visualizar 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, é possível conferir os modificadores como nós wrapper para o layout. nós:

Código para elementos combináveis e modificadores, além da representação visual deles como uma árvore da interface.
Figura 1. Modificadores que envolvem nós de layout na árvore da interface.

Adicionar mais de um modificador a um elemento combinável cria uma cadeia de modificadores. Quando você encadeia vários modificadores, e cada nó de modificador envolve o restante da cadeia e o nó de layout nela. Por exemplo, quando você encadeia uma clip e uma size, o nó modificador clip envolve o nó do modificador size, que encapsula 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 o tamanho e o posicionamento do modificador ou do nó de layout encapsulado.

Como mostrado na Figura 2, a implementação dos elementos combináveis Image e Text em si consistem em uma cadeia de modificadores que envolvem um único nó de layout. O implementações de Row e Column são simplesmente nós de layout que descrevem como organizar seus filhos.

A estrutura de árvore de antes, mas agora cada nó é apenas um layout simples, com muitos modificadores envolvendo nós.
Figura 2. A mesma estrutura de árvore da Figura 1, mas com elementos combináveis na Árvore da interface visualizada como cadeias de modificadores.

Para resumir:

  • Os modificadores unem um único modificador ou nó de layout.
  • Os nós de layout podem dispor vários nós filhos.

As seções a seguir descrevem como usar esse modelo mental para raciocinar o encadeamento de modificadores 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 cada layout. largura, altura e coordenada x, y do nó:

  1. Medir filhos: um nó mede os filhos, se houver.
  2. Decidir o próprio tamanho: com base nessas medidas, um nó decide por conta própria. tamanho.
  3. Colocar filhos: cada nó filho é colocado em relação ao próprio nó posição

O Constraints ajuda a encontrar os tamanhos certos para os nós durante as duas primeiras etapas. etapas do algoritmo. As restrições definem os limites mínimo e máximo largura e altura do nó. Quando o nó decide sobre o tamanho, o tamanho medido devem estar dentro desse intervalo de tamanho.

Tipos de restrições

Uma restrição pode ser uma das seguintes:

  • Limitado: o nó tem largura e altura máximas e mínimas.
Restrições limitadas de diferentes tamanhos em um contêiner.
Figura 3. Restrições limitadas.
  • Ilimitado: o nó não está restrito a nenhum tamanho. A largura máxima e e os limites de altura sejam definidos como infinitos.
.
Restrições ilimitadas com a largura e a altura definidas como infinito. As restrições se estendem além do contêiner.
Figura 4. Restrições ilimitadas.
  • Exata: o nó precisa seguir um requisito de tamanho exato. O mínimo e os limites máximos são definidos com o mesmo valor.
.
Restrições exatas que estão em conformidade com um requisito de tamanho exato no contêiner.
Figura 5. Restrições exatas.
  • 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 define uma largura exata, mas fornece uma altura limitada.
.
Dois contêineres que mostram combinações de restrições limitadas e ilimitadas e larguras e alturas exatas.
Figura 6. Combinações de restrições limitadas e ilimitadas e larguras exatas e alturas.

A próxima seção descreve como essas restrições são passadas de um pai para um criança.

Como as restrições são transmitidas do pai para o filho

Durante a primeira etapa do algoritmo descrita em Restrições no layout fase, as restrições são transmitidas do pai para o filho na árvore da interface.

Quando um nó pai mede seus filhos, ele fornece essas restrições para cada para a criança saber o tamanho dela. Então, quando decide o próprio tamanho, ele também adere às restrições que foram transmitidas os próprios pais.

De modo geral, o algoritmo funciona da seguinte maneira:

  1. Para decidir o tamanho que realmente quer ocupar, o nó raiz na árvore da interface mede os filhos e encaminha as mesmas restrições para o primeiro filho.
  2. Se o filho for um modificador que não afeta a medição, ele vai encaminhar o restrições para o próximo modificador. As restrições são transmitidas para o modificador a cadeia como está, a menos que um modificador que afete a medição seja alcançado. O e as restrições são redimensionadas de acordo com isso.
  3. Quando um nó é alcançado e não tem filhos (chamado de nó"), ele decide o próprio tamanho com base nas restrições que foram passadas, e retorna esse tamanho resolvido ao pai.
  4. o pai adapta as restrições com base nas medidas desse filho. chama o próximo filho com essas restrições ajustadas.
  5. Depois que todos os filhos de um pai forem medidos, o nó pai decide próprio tamanho e comunica isso ao próprio pai.
  6. Dessa forma, toda a árvore é atravessada primeiro em profundidade. Por fim, todos os nós decidiram o tamanho e a etapa de medição foi concluída.

Para ver um exemplo mais detalhado, consulte Restrições e ordem dos modificadores vídeo.

Modificadores que afetam restrições

Na seção anterior, você aprendeu que alguns modificadores podem afetar a restrição tamanho. As seções a seguir descrevem modificadores específicos que afetam restrições.

Modificador size

O modificador size declara o tamanho preferido do conteúdo.

Por exemplo, a árvore da 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:

Uma parte de uma árvore da interface com o modificador de tamanho envolvendo um nó de layout e o
  representação das restrições limitadas definidas pelo modificador de tamanho em um contêiner.
Figura 7. Restrições limitadas na árvore da interface e sua representação em um contêiner.

O modificador size adapta as restrições de entrada para corresponder ao valor transmitido a ele. Neste exemplo, o valor é 150dp:

O mesmo que a Figura 7, exceto com o modificador de tamanho adaptando as restrições de entrada para corresponder ao valor passado a ele.
Figura 8. O modificador size ajusta as restrições para 150dp.

Se a largura e a altura forem menores que o menor limite de restrição, ou maior que o maior limite de restrição, o modificador corresponderá ao o máximo possível, respeitando as restrições passadas em:

Duas árvores da interface e as representações correspondentes em contêineres. Na primeira,
  o modificador de tamanho aceita as restrições de login. Na segunda, o modificador de tamanho se adapta
  restrições muito grandes o mais próximo possível, resultando em restrições que preenchem o contêiner.
Figura 9. O modificador size aderiu à restrição transmitida o máximo possível possível.

O encadeamento de vários modificadores size não funciona. O(a) primeiro(a) size define as restrições mínima e máxima como um valor fixo. Mesmo que o segundo modificador de tamanho solicitar um tamanho menor ou maior, ele ainda precisará aderir aos limites exatos transmitidos, para que não substitua esses valores:

Uma cadeia de dois modificadores de tamanho na árvore da interface e a representação dela em um contêiner.
  que é o resultado do primeiro valor transmitido e não do segundo.
Figura 10. Uma cadeia de dois modificadores size, em que o segundo valor é transmitido. em (50dp) não substitui o primeiro valor (100dp).

Modificador requiredSize

Use o modificador requiredSize em vez de size se precisar que a para substituir as restrições de entrada. O modificador requiredSize substitui as restrições de entrada e passa o tamanho especificado como limites exatos.

Quando o tamanho for retornado para a árvore, o nó filho será centralizado na espaço disponível:

O modificador size e requiredSize encadeados em uma árvore da interface e o
  representação em um contêiner. As restrições do modificador requiredSize substituem o modificador de tamanho
  restrições.
Figura 11. O modificador requiredSize substitui as restrições de entrada do o modificador size.

Modificadores width e height

O modificador size adapta a largura e a altura das restrições. Com modificador width, é possível definir uma largura fixa, mas deixar a altura indecidida. Da mesma forma, com o modificador height, é possível definir uma altura fixa, mas deixe o largura indecidida:

Duas árvores da interface, uma com o modificador de largura e a representação do contêiner dela e a outra
  com o modificador de altura e a representação dele.
Figura 12. O modificador width e o height definem uma largura fixa. e altura, respectivamente.

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.

Uma árvore da interface com o modificador sizeIn com larguras e alturas mínimas e máximas definidas.
  e a representação dele em um contêiner.
Figura 13. O modificador sizeIn com minWidth, maxWidth, minHeight e maxHeight definido.

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)
)

Esse snippet produz a seguinte saída:

  • O modificador fillMaxSize muda as restrições para definir o largura e altura mínimas para o valor máximo: 300dp de largura e 200dp de altura.
  • Mesmo que o modificador size queira usar um tamanho de 50dp, ele ainda precisa a fim de aderir às restrições mínimas de entrada. Portanto, o modificador size vai também gera como saída os limites de restrição exatos de 300 por 200, efetivamente Ignorando o valor fornecido no modificador size.
  • O Image segue esses limites e informa um tamanho de 300 por 200, que passa em toda a árvore.

Image(
    painterResource(R.drawable.hero),
    contentDescription = null,
    Modifier
        .fillMaxSize()
        .wrapContentSize()
        .size(50.dp)
)

Esse snippet produz a seguinte saída:

  • O modificador fillMaxSize adapta as restrições para definir o valor mínimo largura e altura ao valor máximo: 300dp de largura e 200dp pol. a altura.
  • O modificador wrapContentSize redefine as restrições mínimas. Então, embora fillMaxSize resultou em restrições fixas, wrapContentSize a redefiniu a restrições limitadas. O nó a seguir agora pode ocupar todo o espaço novamente ou ser menor do que todo o espaço.
  • O modificador size define as restrições para os limites mínimo e máximo do 50.
  • O Image é resolvido para um tamanho de 50 por 50 e o modificador size para a frente.
  • O modificador wrapContentSize tem uma propriedade especial. Ele usa filho e o coloca no centro dos limites mínimos disponíveis que foram passados para ele. O tamanho que ela comunica aos pais é, portanto, igual ao os limites mínimos que foram passados para ela.

Ao combinar apenas três modificadores, é possível definir um tamanho para o elemento combinável e centralizá-la no pai.

Image(
    painterResource(R.drawable.hero),
    contentDescription = null,
    Modifier
        .clip(CircleShape)
        .padding(10.dp)
        .size(100.dp)
)

Esse snippet 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 como 100dp.
    • O Image segue essas restrições e informa um tamanho de 100 por 100dp
    • O modificador padding adiciona 10dp em todos os tamanhos, então aumenta o largura e altura em 20dp.
    • Agora, na fase de exibição, o modificador clip atua em uma tela de 120 ao 120dp Assim, ele cria uma máscara circular desse tamanho.
    • Em seguida, o modificador padding insere o conteúdo em 10dp em todos os tamanhos, para que ele diminui o tamanho da tela para 100 em 100dp.
    • O Image é desenhado nessa tela. A imagem é recortada com base no círculo original de 120dp, portanto, a saída é um resultado não arredondado.