In Android, ConstraintLayout rappresenta il layout moderno pensato per creare interfacce flessibili e performanti su dispositivi mobili, evitando annidamenti complessi. Questa guida pratica, inoltre, ti mostra come vincolare e posizionare correttamente le tue view per ottenere layout responsive e facili da mantenere. Troverai esempi scritti in Java e sviluppati con Android Studio, così da poterli copiare e adattare subito ai tuoi progetti reali. Seguendo queste indicazioni, riuscirai a sfruttare davvero il potenziale di ConstraintLayout e a rendere le tue schermate professionali e ben organizzate.

Cos’è ConstraintLayout in Android
Con ConstraintLayout Android puoi costruire interfacce estremamente flessibili, anche le più complesse. L’organizzazione si fonda sulle relazioni tra le viste: ogni view viene posizionata definendo vincoli (constraints) rispetto ad altre viste o ai margini del layout padre. Questi rapporti determinano inoltre in che modo gli elementi si ancorano nello spazio disponibile, rendendo il layout meno dipendente da gerarchie profonde. Il risultato è una struttura piatta, priva di numerosi container annidati, che garantisce migliori prestazioni di rendering. Per un’analisi più dettagliata, consulta la reference API ufficiale.
Centrare una view con ConstraintLayout
Per centrare una view nel layout padre, collega al parent tutti e quattro i suoi lati: Top, Start, End e Bottom. In particolare, assicurati che ciascun lato sia correttamente ancorato per garantire l’allineamento desiderato. Ad esempio, il codice seguente centra perfettamente un TextView nello schermo:
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
Posizionare una view negli angoli con ConstraintLayout
In alto a destra con ConstraintLayout
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
In alto a sinistra con ConstraintLayout
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
In basso a destra con ConstraintLayout
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="parent" />
In basso a sinistra con ConstraintLayout
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintBottom_toBottomOf="parent" />
Margini in ConstraintLayout Android
Per introdurre uno spazio tra una view e il vincolo a cui è collegata, puoi usare i seguenti attributi di margine. Inoltre, tali impostazioni ti permettono di controllare con precisione la distanza tra gli elementi:
android:layout_marginStart— margine sinistroandroid:layout_marginEnd— margine destroandroid:layout_marginTop— margine superioreandroid:layout_marginBottom— margine inferiore
<?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"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
app:layout_constraintBottom_toBottomOf="parent"
android:layout_marginBottom="100dp" />
</androidx.constraintlayout.widget.ConstraintLayout>
Bias in ConstraintLayout Android: spostamento lungo l’asse
Il bias ti permette di spostare una view lungo un asse quando è vincolata su entrambi i lati. Di default, il valore è 0.5 (centro). Tuttavia, puoi impostarlo da 0.0 (sinistra/in alto) fino a 1.0 (destra/in basso) per ottenere un posizionamento asimmetrico.
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintHorizontal_bias="0.10" />
Catene in ConstraintLayout Android
Prima di procedere, controlla sempre la versione più recente nelle release notes ufficiali di AndroidX, in modo da utilizzare le funzionalità più aggiornate.
Le catene servono a distribuire un gruppo di viste lungo un asse, orizzontale o verticale. Affinché funzionino correttamente, le viste devono essere collegate tra loro in modo bidirezionale. In altri termini, ciascun elemento deve avere vincoli sia verso il predecessore sia verso il successore della catena.
Catena orizzontale in ConstraintLayout Android
<?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/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button 1"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toLeftOf="@+id/button2" />
<Button
android:id="@+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button 2"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toRightOf="@+id/button1"
app:layout_constraintRight_toLeftOf="@+id/button3" />
<Button
android:id="@+id/button3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button 3"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toRightOf="@+id/button2"
app:layout_constraintRight_toRightOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
Catena verticale in ConstraintLayout Android
<Button
android:id="@+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button 2"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@+id/button1"
app:layout_constraintBottom_toTopOf="@+id/button3" />
<Button
android:id="@+id/button3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button 3"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@+id/button2"
app:layout_constraintBottom_toBottomOf="parent" />
Stile delle catene in ConstraintLayout Android (chainStyle)
Per controllare come si distribuiscono gli elementi di una catena, puoi utilizzare gli attributi app:layout_constraintHorizontal_chainStyle oppure app:layout_constraintVertical_chainStyle. È importante ricordare, inoltre, che questi attributi devono essere impostati esclusivamente sul primo elemento della catena affinché la distribuzione funzioni correttamente. Di seguito trovi i valori disponibili:
| Valore | Comportamento |
|---|---|
spread | Distribuisce gli elementi uniformemente nello spazio disponibile (default) |
packed | Raggruppa gli elementi al centro dello spazio disponibile |
spread_inside | Il primo e l’ultimo elemento sono sui bordi; gli altri distribuiti nel mezzo |
<Button
android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button 1"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toTopOf="@+id/button2"
app:layout_constraintVertical_chainStyle="spread_inside" />