Android

20 jun, 2017

Como usar o Constraint Layout no Android

Publicidade

Então, você não aguenta mais se estressar com o editor visual de layouts do Android Studio? Adoraria ter algo mais confiável, prático e fiel ao que vai “aparecer” no smartphone do seu usuário, em semelhança ao que tem no Delphi e Visual Basic? Essas são algumas das promessas do Google com a criação do mais novo gerenciador de layouts da plataforma Android, o Constraint Layout.

O ConstraintLayout permite que você crie layouts grandes e complexos com uma hierarquia flat no seu XML (sem a necessidade de ficar aninhando um monte de layouts uns dentro dos outros). Ele é similar ao Relative Layout, uma vez que todas suas views se relacionam entre si e com o parent, mas é mais flexível do que seu antecessor e mais fácil de usar com o Layout Editor, do Android Studio. Não obstante, o ConstraintLayout também possui as melhores características do LinearLayout, que era sua responsividade baseada em pesos, o que nos permite interfaces mais fluidas, bem distribuídas e simples de construir. Tudo em um só layout manager!

Mas…deve ser complicado de criar telas com ele, certo?

Errado! Todo o poder do ContraintLayout é disponibilizado diretamente a partir do Layout Editor do Android Studio que foi remodelado pensando nesse layout manager, para que você pudesse construir um layout com ConstraintLayout inteiramente arrastando e soltando componentes, sem ter de editar o XML.

Ah, mas então deve funcionar só nas versões mais recentes do Android, tipo a Nougat…

Errou novamente! O ConstraintLayout está disponível em uma biblioteca de API compatível com Android 2.3 (API 9) ou superiores e neste artigo, baseado na documentação oficial do Constraint Layout, você vai ver um overview deste novo recurso da plataforma, e por que não dizer, do Android Studio!

Para ver diversos exemplos de layouts que você pode criar com ConstraintLayout, dê uma olhada no projeto Constraint Layout Examples no GitHub.

Se você está começando agora com Android, sugiro começar por esse texto aqui, bem mais simples.

Entendendo as Constraints

Constraints significa algo como “restrições” ou “limitações”, e são essas restrições que são o cerne por trás do funcionamento deste layout manager, sendo fundamentais para sua utilização entendê-las primeiro.

Para definir a posição de uma view no ConstraintLayout, você deve adicionar ao menos uma constraint horizontal e uma vertical para a view. Cada constraint representa uma conexão ou alinhamento em relação à outra view, o layout parent ou mesmo uma linha-guia invisível (??). Cada constraint define a posição da view a partir de seus eixos vertical e horizontal; motivo pelo qual temos de definir no mínimo essas duas constraints, embora seguidamente precisaremos de mais de duas para conseguir os comportamentos desejados.

Quando você arrasta e solta uma view no Layout Editor, ela fica exatamente onde você a deixar, mesmo que não possua constraint alguma. No entanto, isso é apenas para tornar o seu trabalho mais fácil quando estiver posicionando os elementos; se uma view não possui constraints, ela ficará no canto superior esquerdo da tela automaticamente (0,0).

Na figura abaixo, o layout parece ok no editor, mas não há constraint vertical na view C. Quando este layout renderizar em um dispositivo, a view C se alinhará horizontalmente com as faces esquerda e direita da view A, mas irá aparecer no topo da tela porque não há constraint vertical.

O correto seria adicionar uma constraint vertical entre as views A e C, como mostra a figura abaixo:

Embora a falta de uma constraint não cause um erro de compilação, o Layout Editor indicará a falta de constraints como um erro na toolbar. Para ajudar você a não esquecer de constraints, o Layout Editor pode automaticamente adicionar as constraints para você com os recursos Autoconnect e “infer constraints” que são novidades na ferramenta.

ConstraintLayout em projetos já existentes

Se faz tempo que você não atualiza o seu Android Studio, pode ser que a opção do ConstraintLayout ainda não esteja aparecendo para você. Esse é o layout manager que vem por padrão quando você cria um novo projeto no Android Studio com uma Empty Activity. Caso você já tenha um projeto existente e queira passar a usar esse recurso, ele também não irá aparecer por padrão para você, se o projeto for muito antigo.

Se algum desses dois cenários for o seu, siga os passos abaixo:

  1. Vá no menu Tools > Android > SDK Manager ou clique no ícone do SDK Manager na toolbar;
  2. No SDK Manager, selecione a aba SDK Tools;
  3. Dentro da aba SDK Tools, expanda o nó Support Repository e, então, marque as opções “ConstraintLayout for Android” e “Solver for ConstraintLayout”. Antes de mandar baixar, marque a opção “Check package details” e verifique a versão de pacote que você está baixando (anote, você vai precisar dessa informação depois);
  4. Mande baixar os pacotes clicando em Ok;
  5. Depois de baixar, adicione a biblioteca do ConstraintLayout como uma dependência no build.gradle da sua aplicação, como no exemplo abaixo:
    dependencies {
        compile 'com.android.support.constraint:constraint-layout:1.0.1'
    }

    Note que a versão ‘1.0.1’ neste exemplo deve ser ajustada de acordo com a versão da sua biblioteca (que eu mandei você anotar no passo 3, lembra?!).

  6. Após modificar o build.gradle e salvar, o Android Studio vai exibir uma notificação para você sincronizar todo o projeto novamente. Faça.

Outra opção é você converter o seu layout antigo para o ConstraintLayout. Você pode fazê-lo seguindo esses passos:

  1. Abra o seu layout no Android Studio e clique na aba Design no rodapé da janela do editor.
  2. Na aba lateral Component Tree (imagem abaixo), clique com o botão direito no layout raiz e selecione a opção “Convert layout to ConstraintLayout”.

Já para adicionar novos arquivos de layout usando o ConstraintLayout como layout raiz, apenas adicione “android.support.constraint.ConstraintLayout” como Root Tag e já era.

Adicionando uma constraint

Vamos começar arrastando um componente qualquer da paleta para o editor visual. Quando você solta o componente, ele exibe bordas ao seu redor com ícones quadrados para redimensionamento nos cantos do componente e ícones circulares para constraints nas laterais dele.

Clique no componente para selecioná-lo. Então, clique e segure um dos ícones circulares (manipuladores de constraints) arrastando até um ponto de ancoragem disponível (a face de outro componente, do parent layout ou uma linha-guia). Quando você soltar, a constraint será criada, com uma margem default separando os dois componentes, como mostrado abaixo:

Quando estiver criando constraints, lembre-se das seguintes regras:

  • Cada componente deve ter ao menos duas constraints: uma vertical e uma horizontal;
  • Você pode criar constraints somente entre um constraint handle (o ícone circular) e um ponto de ancoragem que compartilhem o mesmo plano, ou seja, vertical com vertical e horizontal com horizontal;
  • Cada constraint handle pode ser usado para apenas uma constraint, mas você pode criar várias contraints (de diferentes componentes) para um mesmo ponto de ancoragem.

Para remover uma constraint, seleciona a view e então clique no constraint handle. Ou remova todas constraints selecionando a view e depois clicando em “Clear Constraints”.

Se você adicionar constraints opostas em um componente, as linhas da constraint se tornam serrilhadas como na imagem abaixo, indicando forças opostas.

O efeito é mais visível quando o tamanho do componente é definido literalmente ou como “wrap content”, o que, nesse caso, vai fazer com que o componente fique centralizado entre as constraints. Se ao invés disso você quiser que ele fique esticado para preencher o espaço entre as duas constraints, troque o tamanho para “match constraints”; caso contrário (se quiser manter o tamanho original), ajuste suas constraints de acordo.

Outra alternativa bem comum para usar constraints é para fixar componentes em um dos lados do layout raiz, como abaixo:

Uma técnica ainda mais avançada (e poderosa) é adicionar linhas-guia (guidelines) em seu layout e conectar as constraints dos seus componentes à elas, como se fossem pontos de ancoragem. Para criar uma guideline, clique no ícone correspondente na toolbar, selecionando uma das opções (Add Vertical Guideline ou Add Horizontal Guideline), como na imagem abaixo:

Ajustando o tamanho dos componentes

Você pode usar os cantos do seu componente para redimensioná-lo, mas isso não é recomendado, uma vez que adiciona um valor de largura e altura literal à ele, impedindo-o de se ajustar às diferentes resoluções de telas. Para selecionar modos de redimensionamento mais espertos, clique no componente e abra a janela de propriedades dele no lado direito do editor.

Próximo ao topo da janela de propriedades está o View Inspector, que inclui controles para muitas propriedades de layout, como mostrado na figura abaixo (disponível apenas para layouts usando ConstraintLayout):

Esta janela inclui controles para 1) proporção do tamanho, 2) excluir constraints, 3) modo de altura e largura, 4) margens e 5) viés das constraints (tipo um offset).

O item 3), especialmente, permite que a gente defina como que a altura e largura do componente será calculada.

  • Wrap Content (ícone de setas): clássico, o tamanho é ajustado conforme o conteúdo;
  • Match Constraints (ícone serrilhado): o componente se estica para preencher as constraints, excluindo margens. Usar esse modo permite definir uma proporção de tamanho (16:9, por exemplo);
  • Fixed (ícone reto): valores literais, não recomendado.

Para alternar entre estes modos, basta apenas clicar no símbolo do modo na View Inspector (item 3 na imagem anterior). Para alterar a margem padrão definida pela ferramenta, use o ícone de margem da toolbar, como na imagem abaixo:

Ligando grupos de componentes

Um grupo de componentes pode ser ligado usando constraints bi-direcionais uns com os outros, como mostrado na imagem abaixo,onde temos dois componentes com constraints horizontais um no outro, criando uma corrente ou cadeia horizontal (chain).

Uma corrente permite que você distribua os componentes horizontalmente ou verticalmente com os seguintes estilos (consulte a figura e a explicação mais abaixo):

  1. Spread: default, os componentes são distribuídos de maneira uniforme, após suas margens serem calculadas;
  2. Spread inside: são respeitadas as constraints de cada extremidade e o restante do espaço é distribuído uniformemente;
  3. Weighted: quando a corrente é definida como Spread ou Spread Inside, você pode colocar o tamanho de seus componentes como “match constraint” para que eles ocupem todo o espaço disponível uniformemente. Caso deseje que um componente ocupe mais espaço que o outro, você pode definir pesos diferenciados para eles usando as propriedades layout_constraintHorizontal_weight e layout_constraintVertical_weight, assim como funcionava no LinearLayout clássico;
  4. Packed: os componentes ficam grudados uns nos outros.

Para criar uma corrente de componentes rapidamente, selecione todos eles e depois com o clique direito do mouse, escolha Center Horizontally ou Center Vertically, para criar a corrente na respectiva orientação.

Criando constraints automaticamente

Ao invés de adicionar constraints manualmente em cada um dos seus componentes, você pode adicionar todos eles nas posições que desejar e então clicar no botão Infer Constraints (o ícone de estrelinhas brilhantes) para criar constraints automáticas.

O Infer Constraints escaneia o layout para determinar o conjunto de constraints mais eficiente para todos os componentes. Ele faz o melhor possível para manter todos os componentes nas posições atuais ao mesmo tempo que tenta deixar o layout flexível. Obviamente, alguns ajustes posteriores podem ser necessários para garantir que o layout realmente ficará responsivo.

Autoconnect é outra feature separada que pode ser ligada e desligada. Quando ligada, ela automaticamente cria duas ou mais constraints para cada componente que você arrastar para o layout, mas somente considerando constraints ao parent layout, nunca a outros componentes. Por padrão, esta opção vem desabilitada, mas você pode habilitá-la apenas clicando em seu ícone na toolbar do Editor de Layout (um ícone de U).

Espero que tenham gostado deste artigo. Em breve, pretendo reescrever alguns textos antigos que usavam outros layout managers para este, bem como vou atualizar meu livro digital de Android para fornecer apenas exemplos com ConstraintLayout, que tem se mostrado muito melhor do que os layouts anteriores.

Se você já adquiriu meu livro pela Amazon, você receberá a atualização automaticamente em seu dispositivo de leitura (caso as atualizações automáticas estejam habilitadas).

Até a próxima!