Criar uma interface responsiva com o ConstraintLayout Parte do Android Jetpack.
O ConstraintLayout
permite criar layouts grandes e complexos com uma hierarquia de visualização plana, sem
grupos de visualização aninhados. Ele é semelhante a
RelativeLayout
,
em que todas as visualizações são dispostas de acordo com as relações entre visualizações irmãs
e o layout pai, mas é mais flexível que RelativeLayout
e mais fácil de usar com o Layout Editor do Android Studio.
Todo o poder do ConstraintLayout
está disponível diretamente nas
ferramentas visuais do Layout Editor, porque a API de layout e o Layout Editor são
especialmente criados um para o outro. Você pode criar seu layout com
ConstraintLayout
inteiramente arrastando em vez de editar o
XML.
Esta página mostra como criar um layout com ConstraintLayout
no
Android Studio 3.0 ou mais recente. Para mais informações sobre o Layout Editor,
consulte Criar uma interface com o Layout Editor.
Para conferir uma variedade de layouts que você pode criar com o ConstraintLayout
,
confira o
projeto de exemplos de layout restrito no GitHub (link em inglês).
Visão geral sobre restrições
Para definir a posição de uma visualização no ConstraintLayout
, adicione
pelo menos uma restrição horizontal e uma vertical para a visualização. Cada restrição
representa uma conexão ou alinhamento para outra visualização, o layout pai ou uma
diretriz invisível. Cada restrição define a posição da visualização ao longo do
eixo vertical ou horizontal. Cada visualização precisa ter pelo menos uma restrição para
cada eixo, mas muitas vezes mais são necessárias.
Quando você solta uma visualização no Layout Editor, ela permanece onde você a deixou, mesmo que não haja restrições. Isso é apenas para facilitar a edição. Se uma visualização não tiver restrições quando você executar o layout em um dispositivo, ela será desenhada na posição [0,0] (o canto superior esquerdo).
Na Figura 1, o layout fica bem no editor, mas não há restrição vertical na visualização C. Quando esse layout é colocado em um dispositivo, a visualização C fica alinhada horizontalmente às extremidades esquerda e direita da visualização A, mas aparece na parte de cima da tela, porque não tem restrição vertical.
Embora uma restrição ausente não cause um erro de compilação, o Layout Editor indica a ausência de restrições como um erro na barra de ferramentas. Para conferir os erros e outros avisos, clique em Show Warnings and Errors . Para ajudar a evitar a ausência de restrições, o Layout Editor adiciona automaticamente restrições com os recursos Autoconnect e infer constraints.
Adicionar ConstraintLayout ao seu projeto
Para usar ConstraintLayout
no seu projeto, faça o seguinte:
- Verifique se o repositório
maven.google.com
está declarado no arquivosettings.gradle
:Groovy
dependencyResolutionManagement { ... repositories { google() } )
Kotlin
dependencyResolutionManagement { ... repositories { google() } }
- Adicione a biblioteca como uma dependência no arquivo
build.gradle
do módulo, conforme mostrado no exemplo a seguir. A versão mais recente pode ser diferente da mostrada no exemplo.Groovy
dependencies { implementation "androidx.constraintlayout:constraintlayout:2.2.0-beta01" // To use constraintlayout in compose implementation "androidx.constraintlayout:constraintlayout-compose:1.1.0-beta01" }
Kotlin
dependencies { implementation("androidx.constraintlayout:constraintlayout:2.2.0-beta01") // To use constraintlayout in compose implementation("androidx.constraintlayout:constraintlayout-compose:1.1.0-beta01") }
- Na barra de ferramentas ou na notificação de sincronização, clique em Sync Project with Gradle Files.
Agora você está pronto para criar seu layout com o ConstraintLayout
.
Converter um layout
Para converter um layout já existente em um layout restrito, siga estas etapas:
- Abra o layout no Android Studio e clique na guia Design na parte de baixo da janela do editor.
- Na janela Component Tree, clique com o botão direito do mouse no layout e clique em Convert LinearLayout to ConstraintLayout.
Criar um novo layout
Para iniciar um novo arquivo de layout restrito, siga estas etapas:
- Na janela Project, clique na pasta do módulo e selecione File > New > XML > Layout XML.
- Digite um nome para o arquivo de layout e "androidx.constraintlayout.widget.ConstraintLayout" para a tag raiz.
- Clique em Finish.
Adicionar ou remover uma restrição
Para adicionar uma restrição, faça o seguinte:
Arraste uma visualização da janela Palette para o editor.
Quando você adiciona uma visualização em um
ConstraintLayout
, ela aparece em uma caixa delimitadora com alças de redimensionamento quadradas em cada canto e alças circulares de restrição em cada lado.- Clique na visualização para selecioná-la
- Escolha uma destas opções:
- Clique em uma alça de restrição e arraste-a para um ponto de fixação disponível. Esse ponto pode ser a borda de outra visualização, a borda do layout ou uma linha guia. Observe que, conforme você arrasta a alça de restrição, o Layout Editor mostra possíveis âncoras de conexão e sobreposições azuis.
Clique em um dos botões Create a connection na seção Layout da janela Attributes, como mostrado na figura 4.
Quando a restrição é criada, o editor fornece uma margem padrão para separar as duas visualizações.
Ao criar restrições, lembre-se das seguintes regras:
- Cada visualização precisa ter pelo menos duas restrições: uma horizontal e uma vertical.
- Você só pode criar restrições entre uma alça de restrição e um ponto de fixação que compartilham o mesmo plano. Um plano vertical (os lados esquerdo e direito) de uma visualização só pode ser restrito a outro plano vertical, e as linhas de base só podem ser restritas a outras linhas de base.
- Cada alça de restrição só pode ser usada para uma única restrição, mas você pode criar várias restrições de diferentes visualizações para o mesmo ponto de fixação.
Você pode excluir uma restrição realizando uma das seguintes ações:
- Clique em uma restrição para selecioná-la e clique em Excluir.
Clique com a tecla Control pressionada (Command no Mac) em um ponto de fixação de restrição. A restrição fica vermelha para indicar que você pode clicar para excluí-la, conforme mostrado na Figura 5.
Na seção Layout da janela Attributes, clique em um ponto de fixação de restrição, como mostrado na figura 6.
Se você adicionar restrições opostas em uma visualização, as linhas de restrição vão se enrolar como uma mola para indicar as forças opostas, como mostrado no vídeo 2. O efeito é mais visível quando o tamanho da visualização é definido como "fixed" ou "wrap content". Nesse caso, a visualização é centralizada entre as restrições. Se, em vez disso, você quiser que a visualização estenda o tamanho dela para atender às restrições, mude o tamanho para "match constraints". Se você quiser manter o tamanho atual, mas mover a visualização de modo que não fique centralizada, ajuste o viés da restrição.
Você pode usar restrições para atingir diferentes tipos de comportamento de layout, conforme descrito nas seções a seguir.
Posição do pai
Restringir o lado de uma visualização à borda correspondente do layout.
Na Figura 7, o lado esquerdo da visualização está conectado à borda esquerda do layout pai. Você pode definir a distância a partir da borda com margem.
Posição da ordem
Defina a ordem de exibição de duas visualizações, vertical ou horizontalmente.
Na figura 8, B está restrito a estar sempre à direita de A, e C está restrito abaixo de A. No entanto, essas restrições não implicam alinhamento, de modo que B ainda possa se mover para cima e para baixo.
Alinhamento
Alinhe a borda de uma visualização com a mesma borda de outra.
Na figura 9, o lado esquerdo de B está alinhado com o lado esquerdo de A. Para alinhar os centros de uma visualização, crie uma restrição em ambos os lados.
Você pode deslocar o alinhamento arrastando a visualização para dentro a partir da restrição. Por exemplo, a figura 10 mostra B com um alinhamento de deslocamento de 24 dp. O deslocamento é definido pela margem da visualização restrita.
Você também pode selecionar todas as visualizações que quer alinhar e clicar em Align na barra de ferramentas para selecionar o tipo de alinhamento.
Alinhamento da linha de base
Alinhe a linha de base do texto de uma visualização à linha de base do texto de outra.
Na figura 11, a primeira linha de B está alinhada com o texto em A.
Para criar uma restrição de valor de referência, clique com o botão direito do mouse na visualização de texto que você quer restringir e clique em Show Baseline. Em seguida, clique na linha de base do texto e arraste a linha para outra.
Restringir a uma linha guia
Você pode adicionar uma diretriz vertical ou horizontal que permita restringir as visualizações e que fique invisível para os usuários do app. Você pode posicionar a linha guia dentro do layout com base nas unidades de dp ou em uma porcentagem relativa à borda do layout.
Para criar uma linha guia, clique em Guidelines na barra de ferramentas e em Add Vertical Guideline ou Add Horizontal Guideline.
Arraste a linha pontilhada para reposicioná-la e clique no círculo na borda da guia para alternar o modo de medição.
Restringir a uma barreira
Assim como uma linha guia, uma barreira é uma linha invisível à qual você pode restringir as visualizações, exceto que uma barreira não define a própria posição. Em vez disso, a posição da barreira se move com base na posição das visualizações contidas nela. Isso é útil quando você quer restringir uma visualização a um conjunto de visualizações em vez de uma específica.
Por exemplo, na Figura 13, a visualização C está restrita ao lado direito de uma barreira. A barreira é definida como "extremidade" (ou o lado direito, em um layout da esquerda para a direita) da visualização A e da visualização B. A barreira se move dependendo se o lado direito da visualização A ou da visualização B está mais à direita.
Para criar uma barreira, siga estas etapas:
- Clique em Guidelines na barra de ferramentas e clique em Add Vertical Barrier ou Add Horizontal Barrier.
- Na janela Component Tree, selecione as visualizações que você quer que estejam dentro da barreira e arraste-as para o componente de barreira.
- Selecione a barreira na Component Tree, abra a janela Attributes e defina barrierDirection.
Agora você pode criar uma restrição de outra visualização para a barreira.
Você também pode restringir à barreira as visualizações que estão dentro dela. Dessa forma, você pode alinhar todas as visualizações na barreira entre si, mesmo que não saiba qual é a mais longa ou mais alta.
Você também pode incluir uma linha guia dentro de uma barreira para garantir uma posição "mínima" para ela.
Ajustar o viés da restrição
Quando você adiciona uma restrição aos dois lados de uma visualização e o tamanho dela é "fixo" ou "encapsulamento de conteúdo", a visualização fica centralizada entre as duas restrições com um viés de 50% por padrão. Você pode ajustar o viés arrastando o controle deslizante na janela Attributes ou arrastando a visualização, como mostrado no vídeo 3.
Se, em vez disso, você quiser que a visualização estenda o tamanho dela para atender às restrições, mude o tamanho para "match constraints".
Ajustar o tamanho da visualização
Você pode usar as alças dos cantos para redimensionar uma visualização, mas isso codifica o tamanho, ou seja, a visualização não é redimensionada para diferentes tamanhos de tela ou de conteúdo. Para selecionar um modo de dimensionamento diferente, clique em uma visualização e abra a janela Attributes no lado direito do editor.
Perto da parte de cima da janela Attributes está o inspetor de visualizações, que inclui controles para vários atributos de layout, como mostrado na figura 14. Ela está disponível apenas para visualizações em um layout de restrição.
Você pode mudar a forma como a altura e a largura são calculadas clicando nos símbolos indicados com a frase de destaque 3 na figura 14. Esses símbolos representam o modo de tamanho da seguinte maneira. Clique no símbolo para alternar entre essas configurações:
- Fixed: especifique uma dimensão específica na caixa de texto a seguir ou redimensione a visualização no editor.
- Wrap Content: a visualização se expande apenas o necessário para ajustar o conteúdo.
- layout_restrictedWidth (link em inglês)
-
Match Constraints: a visualização se expande o máximo possível para atender às
restrições de cada lado, depois de contabilizar as margens da visualização. No entanto, é possível
modificar esse comportamento com os atributos e valores a seguir. Esses
atributos só entram em vigor quando você define a largura da visualização para "match constraints":
- layout_constraintWidth_min
Isso leva uma dimensão
dp
para a largura mínima da visualização. - layout_constraintWidth_max
Isso leva uma dimensão
dp
para a largura máxima da visualização.
No entanto, se a dimensão especificada tiver apenas uma restrição, a visualização se expandirá para caber o conteúdo. O uso desse modo na altura ou na largura também permite definir uma proporção de tamanho.
- layout_constraintWidth_min
Defina como true
para permitir que a dimensão horizontal mude para respeitar as restrições. Por padrão, um widget definido como WRAP_CONTENT
não é limitado por restrições.
Definir o tamanho como uma proporção
É possível definir o tamanho da visualização para uma proporção, como 16:9, se pelo menos uma das
dimensões da visualização estiver definida como "match constraints" (0dp
). Para ativar a
proporção, clique em Toggle Aspect Ratio Constraint (frase de destaque
1 na Figura 14) e insira a
proporção width:height na entrada que aparece.
Se a largura e a altura estiverem definidas para "match constraints", clique em Toggle Aspect Ratio Constraint para selecionar a dimensão com base na proporção da outra. O inspetor de visualização indica qual dimensão é definida como uma proporção conectando as bordas correspondentes com uma linha sólida.
Por exemplo, se você definir ambos os lados como "match constraints", clique em Toggle Aspect Ratio Constraint duas vezes para definir a largura como uma proporção da altura. O tamanho total é determinado pela altura da visualização, que pode ser definida de qualquer forma, conforme mostrado na Figura 15.
Ajustar as margens da visualização
Para fazer com que as visualizações fiquem espaçadas uniformemente, clique em Margin na barra de ferramentas para selecionar a margem padrão de cada visualização adicionada ao layout. Qualquer alteração feita na margem padrão se aplica somente às visualizações adicionadas a partir de então.
Você pode controlar a margem de cada visualização na janela Attributes, clicando no número da linha que representa cada restrição. Na Figura 14, a frase de destaque 4 mostra que a margem inferior está definida como 16dp.
Todas as margens oferecidas pela ferramenta são fatores de 8 dp para ajudar a alinhar as visualizações às recomendações de grade quadrada de 8 dp do Material Design.
Controlar grupos lineares com uma cadeia
Uma cadeia é um grupo de visualizações vinculadas umas às outras com restrições de posição bidirecionais. As visualizações em uma cadeia podem ser distribuídas verticalmente ou horizontalmente.
As cadeias podem ser estilizadas de uma das seguintes maneiras:
- Spread:as visualizações são distribuídas uniformemente depois que as margens são contabilizadas. Esse é o padrão.
- Spread inside:a primeira e a última visualizações ficam fixadas nas restrições de cada extremidade da cadeia, e o restante é distribuído uniformemente.
- Ponderado:quando a cadeia está definida como spread ou
spread inside, é possível preencher o espaço restante definindo uma ou mais
visualizações como "match constraints" (
0dp
). Por padrão, o espaço é distribuído uniformemente entre cada visualização definida como "match constraints", mas é possível atribuir um peso de importância a cada visualização usando os atributoslayout_constraintHorizontal_weight
elayout_constraintVertical_weight
. Isso funciona da mesma maneira quelayout_weight
em um layout linear: a visualização com o maior valor ponderado recebe mais espaço, e as visualizações com o mesmo peso recebem a mesma quantidade de espaço. - Packed:as visualizações são agrupadas depois que as margens são contabilizadas. Ajuste o viés de toda a cadeia (para a esquerda, para a direita ou para cima ou para baixo) mudando o viés de visualização da "cabeça" da cadeia.
A visualização principal da cadeia, que corresponde à visualização mais à esquerda em uma cadeia horizontal (em um layout da esquerda para a direita) e à visualização superior em uma cadeia vertical, define o estilo da cadeia em XML. No entanto, você pode alternar entre spread, spread inside e packed selecionando qualquer visualização na cadeia e clicando no botão de cadeia que aparece abaixo da visualização.
Para criar uma cadeia, faça o seguinte, conforme mostrado no vídeo 4:
- Selecione todas as visualizações que serão incluídas na cadeia.
- Clique com o botão direito do mouse em uma das visualizações.
- Selecione Redes.
- Selecione Centralizar horizontalmente ou Centralizar verticalmente.
Confira alguns pontos a serem considerados ao usar cadeias:
- Uma visualização pode fazer parte de uma cadeia vertical e horizontal, facilitando a criação de layouts de grade flexíveis.
- Uma cadeia só funciona corretamente se cada extremidade está restrita a outro objeto no mesmo eixo, como mostrado na figura 14.
- Embora a orientação de uma cadeia seja vertical ou horizontal, o uso de uma não alinha as visualizações naquela direção. Para alcançar a posição adequada para cada visualização na cadeia, inclua outras restrições, como restrições de alinhamento.
Criar restrições automaticamente
Em vez de adicionar restrições a cada visualização à medida que você as coloca no layout, é possível mover cada visualização para as posições desejadas no Layout Editor e clicar em Infer Constraints para criar restrições automaticamente.
Infer Constraints verifica o layout para determinar o conjunto de restrições mais eficaz para todas as visualizações. Ele restringe as visualizações às posições atuais, proporcionando flexibilidade. Talvez seja necessário fazer ajustes para que o layout responda da forma que você pretende para diferentes tamanhos de tela e orientações.
Autoconnect to Parent é um recurso separado que você pode ativar. Quando ele está ativado e você adiciona visualizações filhas a uma mãe, esse recurso cria automaticamente duas ou mais restrições para cada visualização à medida que são adicionadas ao layout, mas somente quando é apropriado restringir a visualização ao layout pai. A conexão automática não cria restrições para outras visualizações no layout.
O recurso de conexão automática fica desativado por padrão. Para ativar, clique em Enable Autoconnection to Parent na barra de ferramentas do Layout Editor.
Animações de frames-chave
Em um ConstraintLayout
, você pode animar mudanças no tamanho
e na posição dos elementos usando
ConstraintSet
e
TransitionManager
.
Um ConstraintSet
é um objeto leve que representa as
restrições, as margens e o preenchimento de todos os elementos filhos em um
ConstraintLayout
. Quando você aplica um ConstraintSet
a um
ConstraintLayout
mostrado, o layout atualiza as restrições de
todos os filhos.
Para criar uma animação usando ConstraintSet
, especifique dois arquivos de layout
que funcionam como frames-chave de início e fim da animação. Você pode carregar
um ConstraintSet
do segundo arquivo de frames-chave e aplicá-lo ao
ConstraintLayout
exibido.
O exemplo de código a seguir mostra como animar movendo um único botão para a parte de baixo da tela.
// MainActivity.kt
fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.keyframe_one)
constraintLayout = findViewById(R.id.constraint_layout) // member variable
}
fun animateToKeyframeTwo() {
val constraintSet = ConstraintSet()
constraintSet.load(this, R.layout.keyframe_two)
TransitionManager.beginDelayedTransition()
constraintSet.applyTo(constraintLayout)
}
// layout/keyframe1.xml // Keyframe 1 contains the starting position for all elements in the animation // as well as final colors and text sizes. <?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent"> <Button android:id="@+id/button2" android:layout_width="0dp" android:layout_height="wrap_content" android:text="Button" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> </androidx.constraintlayout.widget.ConstraintLayout>
// layout/keyframe2.xml // Keyframe 2 contains another ConstraintLayout with the final positions. <?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent"> <Button android:id="@+id/button2" android:layout_width="0dp" android:layout_height="wrap_content" android:text="Button" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintBottom_toBottomOf="parent" /> </androidx.constraintlayout.widget.ConstraintLayout>
Outros recursos
ConstraintLayout
é usado no
app de demonstração
Sunflower.