Concrete Logo
Hamburger button

ConstraintLayout: The Ultimate ViewGroup

  • Blog
  • 11 de Maio de 2018

O ConstraintLayout foi introduzido pelo Google em 2016, trazendo alguns novos recursos e ferramentas interessantes que vão ajudar você a criar layouts complexos com muito mais facilidade do que provavelmente está acostumado a fazer. Neste post, vamos passar por cada um desses recursos e entendê-los melhor. Vamos lá?

Antes do ConstraintLayout: a “Idade das Trevas”

Antes do surgimento do ConstraintLayout, as coisas eram um pouco difíceis quando se tratava de projetar layouts complexos. Você, normalmente, teria que aninhar diferentes tipos de layouts para obter a aparência desejada.

Digamos que você teria que desenhar esse layout sem ConstraintLayout:

Para fazer isso, você precisaria de pelo menos um layout aninhado dentro do layout raiz, algumas margens e preenchimentos precisamente calculados e talvez colocar algumas views invisíveis como divisores. Para encurtar a longa história, um pesadelo.

A revolução do ConstraintLayout

Felizmente, o ConstraintLayout veio para nos ajudar. E o bom é que suas propriedades e uso são muito fáceis de aprender e de se acostumar, já que ele é compatível com todas as versões do Android a partir da API 9 (Gingerbread). Também funciona muito bem com o designer de layouts do Android Studio.

Se fôssemos projetar exatamente o mesmo layout mencionado no tópico anterior usando o ConstraintLayout, poderíamos colocar todas as views no layout raiz, configurar apenas algumas propriedades e não precisaríamos nos preocupar com a aparência dele em outros tamanhos de tela ou orientações.

Tudo o que você precisa fazer é definir as restrições para cada view. ou seja, a parte superior da view X está vinculada à parte inferior da view Y e assim por diante.

No entanto, o ConstraintLayout não foi feito para que você esqueça todos os outros layouts. Se, por exemplo, o layout que você pretende criar for simples o suficiente para que um LinearLayout ou mesmo um FrameLayout possa manipular o trabalho, basta usá-lo.

Exemplos

Em todos os tópicos a partir de agora, vou dar exemplos de implementação com o designer de layouts e o XML. Sinta-se à vontade para seguir qualquer exemplo com o qual estiver mais confortável. Vou mostrar o que você deve esperar se seguir qualquer um dos exemplos.

Depois de reproduzir os exemplos em seu próprio layout, convido você a fazer testes semelhantes. Use sua criatividade!

Agora vamos parar com essa falação e partir para o código!

1. Adicionando ConstraintLayout ao seu projeto

Para adicionar o ConstraintLayout ao seu projeto, copie e cole no seu arquivo <build.gradle> de nível de projeto, se ele já não estiver lá:

Copie e cole isso no seu arquivo <build.gradle> de nível de módulo:

Por que beta? Porque existem alguma features interessantes como grupos e barreiras, nas quais vamos dar uma olhada um pouco mais para a frente.

2. Colocar e restringir views

Restrições são regras que você define para posicionar uma view em relação à outra. Neste exemplo, vamos colocar um TextView no centro do layout e um botão logo abaixo dele.

2.1. UI designer

Para colocar este TextView no centro do layout, arraste e solte um TextView da paleta em qualquer lugar do layout; arraste o círculo (restrição) na parte superior do TextView e solte-o na parte superior do layout “pai”, conforme mostrado na imagem acima.

Em seguida, faça o mesmo com as outras restrições: restrição à direita no lado direito do layout pai e assim por diante.

Agora vamos colocar o botão abaixo do TextView. Assim como você fez com o TextView, coloque um botão em qualquer lugar no layout. Em seguida, arraste a restrição superior do botão para a restrição inferior do TextView, como mostra a imagem abaixo.

E, finalmente, vincule as outras restrições a seus respectivos destinos.

2.2. XML

Vamos usar o ConstraintLayout como o layout raiz, com largura e altura como match_parent.

Agora copie e cole o seguinte conteúdo em seu arquivo XML:

 

2.3. Resultado

Agora, se você seguiu o exemplo do designer da interface do usuário ou o do XML, seu layout deve ficar assim:

Você pode pensar: “e se eu quisesse colocar o botão mais perto ou mais longe do TextView? Seria possível?”. Por enquanto vamos deixar assim, mas já já a gente chega lá.

3. Tendências Horizontal e Vertical

Respondendo à pergunta anterior, sim, é possível somente se definirmos uma tendência.

Você pode definir a tendência horizontal se a visualização estiver restrita à esquerda e à direita, e a polarização vertical se for restrita à parte superior e inferior.

O valor definido como tendência horizontal ou vertical é um número entre 0 e 1, representando uma porcentagem, em que o mais próximo de 0 significa tendendo mais para a esquerda (horizontal) ou para baixo (vertical). E o mais próximo de 1 significa o mais tendendo mais para a direita (horizontal) ou para cima (vertical).

O valor padrão para cada tendência é 50% (UI Designer) e 0.5 (XML), ou seja, entre as restrições de esquerda e da direita (horizontal) ou as restrições de cima e de baixo (vertical).

Agora vamos definir um tendência horizontal para o mesmo TextView e uma vertical para o botão:

3.1. UI Designer

Clique no TextView e, no painel de atributos, arraste a barra horizontal até que o valor seja 25.

Agora clique no botão e arraste a barra vertical para definir o valor para 0.

3.2. XML

Adicione a linha abaixo à tag TextView:

E esta linha para a tag Button:

3.3. Resultado

O resultado que você deve esperar é esse:

Agora, tente definir suas próprias tendências para essas views até que elas estejam exatamente onde você deseja.

4. O valor match_constraint

Digamos que você queira colocar um EditText ao lado de uma ImageView para criar algo semelhante a um SearchView, e a largura do EditText deve ser a mesma do “layout pai”, excluindo os do ImageView. Isso seria um pouco trabalhoso sem o ConstraintLayout. Com ele, porém, é muito fácil!

4.1. UI Designer

Coloque um ImageView em qualquer lugar à esquerda do layout e, em seguida, um EditText à direita, definindo todas as restrições necessárias para as duas visualizações. Em seguida, defina a largura do EditText como “match_constraint”.

4.2. XML

O equivalente em XML a “match_constraint” é 0dp.

Adicione estas linhas ao seu arquivo XML:

4.3. Resultado

O que você deve esperar:

Agora tente algo parecido.

Nota: match_constraint vai funcionar somente em views nas quais ambas as restrições (horizontal para largura ou vertical para altura) estiverem definidas.

5. Restrições da linha de base

Aqui, você vai aprender a restringir uma view à linha de base de outra. Isso geralmente é feito com views relacionadas a texto, como TextView e EditText.

Um exemplo seria alinhar as linhas de base de um TextView e um EditText em que o tamanho do texto do TextView é menor do que o EditText, o que dificultaria o alinhamento das linhas de base de ambas as views.

5.1. UI Designer

Neste exemplo, vamos alinhar a linha de base da EditText com a de TextView.

Clique no botão EditText e no botão ‘ab’ (Edit baseline). Em seguida, arraste a linha de base para a linha de base do TextView.

 

5.2. XML

Depois de colocar e restringir TextView e EditText, adicione a seguinte linha à tag EditText:

Nota: quando você adiciona uma restrição de linha de base, não precisa adicionar as restrições verticais.

5.3. Resultado

Seu layout deve ficar assim:

Agora tente algo parecido.

Ok, isso está ficando muito repetitivo e estou cansado de escrever a mesma coisa depois de cada item “Resultado” haha Então, a partir de agora, você pode subentender que vai ser bom tentar e criar seus próprios exemplos depois de aprender cada tópico. Combinado?

6. Restrições circulares

Basicamente, o que esse recurso faz é colocar uma view em um determinado ângulo (em graus de 0 a 360) e o raio em relação a outra. O raio é a distância entre o centro da sua view e o centro da view de destino.

Agora vamos colocar um ImageView no centro do layout e um Switch a 45 graus e um raio de 100dp.

6.1. UI Designer

Adicione e restrinja o ImageView e o Switch no centro do layout, depois clique no Switch e, no painel de atributos, clique em “view all attributes” e “Constraints”.

Defina o atributo “circle” como o ID da sua view de destino (o ImageView neste exemplo), o “círculo de animação” a 45 e o “circleRadius” a 100 dp.

6.2. XML

Adicione as seguintes linhas à sua tag do Switch:

 

6.3. Resultado

O que você deve esperar:

7. Proporção

Com esse recurso, você pode definir uma proporção para uma view (geralmente ImageView). Neste exemplo, vamos definir uma proporção para um ImageView.

7.1. UI Designer

Coloque e restrinja um ImageView no centro do layout, depois clique na ImageView e defina a largura e a altura como match_constraint.

No painel de atributos, clique no botão “Toggle Aspect Ratio Constraint” e defina a proporção para 16: 9.

7.2: XML

Defina a largura e a altura do ImageView para 0dp e adicione a seguinte linha a ele:

7.3. Resultado

8. Margem para views marcadas como “gone”

Esse recurso permite que você defina uma margem em relação a views, na qual a visibilidade seja “gone”. No exemplo, vamos ter um SeekBar marcado como “gone” na parte superior do layout e um ToggleButton abaixo dele.

8.1. UI Designer

Posicione e restrinja o SeekBar e o ToggleButton no layout, com a restrição superior do ToggleButton conectada à parte inferior do SeekBar e defina a visibilidade do SeekBar como “gone”.

Clique no ToggleButton e, no painel de atributos, defina layout_goneMarginTop como 100dp. Estamos definindo um valor alto para facilitar a demonstração.

8.2. XML

Adicione a seguinte linha à tag ToggleButton:

8.3. Resultado

9. Cadeia de views

Uma cadeia de views é quando uma view A está conectada a uma view B e vice-versa. Por exemplo: uma parte inferior do TextView é conectada ao topo de um botão, e o topo do botão é conectado à parte inferior do TextView.

Pode parecer redundante, mas se houver mais de duas views encadeadas, vai ser mais fácil distribui-las pelo layout usando as propriedades da cadeia.

Existem três tipos de cadeias: “spread” (padrão), “spread inside” e “packed”.

“Spread” vai espalhar todas as views da cadeia em distâncias iguais entre si por meio do layout.

“Spread inside” tem um comportamento semelhante ao “spread”, mas os elementos das extremidades da cadeia não vão se espalhar.

“Packed” vai agrupar as views o mais próximo possível uma da outra.

Você deve definir o tipo de cadeia no primeiro elemento dela: view superior se for vertical, view esquerda se for horizontal.

Agora vamos fazer uma cadeia vertical de 4 EditTexts.

9.1. UI Designer


Coloque 4 EditTexts no layout e conecte-os verticalmente um ao outro. Depois disso, você vai ver uma corrente entre cada par de views.

Como mencionado anteriormente, o estilo de cadeia padrão é “spread”, que vai ser semelhante à imagem acima.

Clique no primeiro elemento da cadeia (elemento superior) e depois clique no botão “Cycle Chain Mode” até ver todos os elementos da cadeia agrupados próximos um do outro.

9.2. XML

Depois de conectar todos os EditTexts verticalmente um ao outro, adicione essa linha ao primeiro elemento da cadeia (elemento superior):

9.3. Resultado

O que você deve esperar:

10. Linhas de guia

Linhas invisíveis que você pode colocar em posições estratégicas do seu layout. Com elas, você pode restringir suas visões à(s) linha(s) de guia para que elas nunca fiquem posicionadas por cima de outras e estejam sempre posicionadas exatamente onde você quer que estejam, independente do tamanho da tela ou orientação.

Existem duas orientações possíveis para uma linha de guia: horizontal e vertical. A horizontal vai da esquerda para a direita do layout, e a vertical, obviamente, da parte superior até a extremidade inferior.

E existem três maneiras de colocar uma linha de guia no layout:

  1. Start: distância da esquerda (vertical) ou superior (horizontal) da linha;
  2. End: distância da direita (vertical) ou inferior (horizontal) da linha;
  3. Percent: porcentagem da largura (vertical) ou altura (horizontal) do layout.;

Vou mostrar um exemplo para cada uma dessas três maneiras usando uma linha de guia horizontal.

10.1. Start

10.1.1. UI Designer

Clique no botão “Guidelines” na barra de ferramentas, no último botão sob os botões “27” e “AppTheme” na imagem. Em seguida, adicione uma linha de guia horizontal.

Clique na linha de guia na árvore de componentes. Se o ícone na linha de guia for diferente de uma seta apontando para cima, basta clicar no ícone até mostrar esse ícone. Agora arraste para cima ou para baixo até ver “100”.

Em seguida, adicione duas views e restrinja uma no topo da diretriz e uma na parte inferior.

10.1.2. XML

Adicione o seguinte ao seu arquivo XML:

 

10.1.3. Resultado

Se você tentar arrastar a linha de guia para cima ou para baixo, as views restritas a ela devem acompanhar.

10.2. End

10.2.1. UI Designer

Faça o mesmo que no exemplo anterior (Begin), mas clique no botão de linha de guia até ver uma seta apontando para baixo e arraste a linha para baixo até ver “100”.

10.2.2. XML

Na tag Guideline, substitua a linha

por

10.2.3. Resultado

10.3. Percent

10.3.1. UI Designer

Ainda com o mesmo exemplo, clique no botão de linha de guia até ver o ícone “%” e arraste-o para o valor de 50%.

10.3.2. XML

No Guideline, substitua:

por:

10.3.3. Resultado


11. Barreiras

A documentação oficial do ConstraintLayout diz:

“Semelhante a uma linha de guia, uma barreira é uma linha invisível à qual você pode restringir as views. Exceto que uma barreira não define sua própria posição; em vez disso, a posição da barreira se move com base na posição das views contidas nela. Isso é útil quando você deseja restringir uma view a um conjunto de views em vez de uma view específica.”

As barreiras podem ser restringidas de qualquer lado. Por exemplo, se você quiser que uma view seja restrita ao topo da view mais alta pertencente à barreira, a direção da barreira deve ser “top”. Você também pode fazer isso com a parte inferior da view mais alta ou a esquerda ou direita da view mais larga da barreira.

Suponha que temos três TextViews e um Button e queremos restringir o Button à esquerda do TextView mais longo, mas não sabemos qual dos três vai ser o mais longo. Então definimos uma barreira contendo os três TextViews e restringimos a esquerda do botão à direita da barreira.

Vamos ver exatamente esse exemplo agora.

11.1. UI Designer

Coloque e restrinja três TextViews à esquerda do layout. Adicione um texto longo ao primeiro, um texto mais curto ao seguinte e um texto muito curto ao último.

Clique em “Guidelines” na barra de ferramentas e depois em “Add Vertical Barrier”.

Clique na barreira na árvore de componentes e defina o atributo “barrierDirection” como “end”. Em seguida, na árvore de componentes, arraste os três TextViews para a barreira.

E, finalmente, adicione um Button ao layout e restrinja sua esquerda à direita da barreira.

11.2. XML

Adicione o código abaixo em seu layout XML:

11.3. Resultado

12. Grupos

Grupos são conjuntos invisíveis para várias views. Eles são úteis quando você deseja alterar a visibilidade de mais de uma view de uma só vez. No exemplo a seguir, vamos ter um grupo com uma cadeia vertical de três EditTexts, que vão ser denominados “editableFields” e outro grupo com uma cadeia vertical de três TextViews, que vão ser chamados de “nonEditableFields”.

12.1. UI Designer

Depois de adicionar as cadeias de EditText e TextView, clique no botão da barra de ferramentas “Guidelines” e, em seguida, clique em “Add Group”. Neste exemplo, adicione dois grupos.

Defina o ID do primeiro grupo para editableFields e o segundo nonEditableFields.

Na árvore de componentes, arraste os três EditTexts para editableFields e os três TextViews para nonEditableFields.

Em seguida, defina a visibilidade de nonEditableFields como “gone”.

12.2. XML

Copie e cole isso no seu XML:

12.3. Resultado

Ao definir a visibilidade de nonEditableFields para “gone”, todos os três TextViews vão desaparecer. Tente fazer o contrário: defina a visibilidade dos editableFields para “gone” em vez dos nonEditableFields.

E é isso! Espero que este texto tenha te ajudado a se sentir mais confortável para usar o ConstraintLayout em seus próprios aplicativos. Tem alguma dúvida ou algo para contribuir? Aproveite os campos abaixo. Até a próxima!

A Concrete, parte da Accenture Technology, é referência em consultoria ágil, facilitando a transformação digital dos clientes ao criar produtos digitais inovadores. Só no capítulo Android contamos com 60 pessoas, que compartilham informações o tempo todo, em talks semanais e treinamentos frequentes. Nossos times têm autonomia para trabalhar e acesso direto aos gerentes, o que facilita a troca de conhecimento e a constante evolução técnica. Quer trabalhar com os melhores? Acesse: concrete.com.br/vagas