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. Gli esempi scritti in Java e sviluppati con Android Studio ti permetteranno di copiarli e adattarli subito ai tuoi progetti reali. Con queste indicazioni, riuscirai a sfruttare davvero il potenziale di ConstraintLayout e a rendere le tue schermate professionali e ben organizzate.

Cos’è ConstraintLayout in Android
Usando ConstraintLayout Android è possibile costruire interfacce estremamente flessibili, anche molto complesse. In questo approccio 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. Tali relazioni determinano inoltre in che modo gli elementi si ancorano nello spazio disponibile, rendendo il layout meno dipendente da gerarchie profonde. Ne deriva 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 ottenere la centratura di 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
Posizionare una view nell’angolo superiore destro
<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" />
View nell’angolo superiore sinistro
<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" />
Posizionamento nell’angolo inferiore destro
<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" />
View nell’angolo inferiore sinistro
<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
Aggiungere uno spazio tra una view e il vincolo a cui è collegata è semplice: puoi usare i seguenti attributi di margine. Queste 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)
Gli attributi app:layout_constraintHorizontal_chainStyle oppure app:layout_constraintVertical_chainStyle controllano come si distribuiscono gli elementi di una catena. È 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" />
Articoli correlati
Barrier e Guideline in ConstraintLayout Android
Le Barrier e le Guideline sono strumenti avanzati di ConstraintLayout Android che ti permettono di gestire layout complessi in modo dinamico e responsivo. Una Guideline rappresenta una linea invisibile (verticale o orizzontale) a cui puoi vincolare più view, mentre una Barrier si sposta automaticamente in base alle dimensioni runtime delle view che raggruppa.
Esempio di Guideline verticale (XML completo)
In questo esempio creiamo una Guideline verticale al 30% della larghezza del parent e allineiamo un TextView a destra della Guideline. Puoi usare questo pattern per layout dashboard o form complessi.
<?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">
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guideline_vertical_30"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintGuide_percent="0.30" <!-- Guideline al 30% della larghezza -->
app:orientation="vertical" />
<TextView
android:id="@+id/titleText"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="Titolo allineato alla Guideline"
android:textSize="18sp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toEndOf="@id/guideline_vertical_30" <!-- parte dalla Guideline -->
app:layout_constraintEnd_toEndOf="parent"
android:layout_margin="16dp" />
</androidx.constraintlayout.widget.ConstraintLayout>
Esempio di Barrier (allineamento dinamico a più view)
Una Barrier è utile quando vuoi posizionare un elemento in base all’ingombro massimo di più view. In questo esempio, un pulsante viene posizionato dopo il testo più lungo tra due TextView.
<?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="wrap_content"
android:padding="16dp">
<TextView
android:id="@+id/labelShort"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Titolo"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent" />
<TextView
android:id="@+id/labelLong"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Titolo molto più lungo che può andare a capo"
app:layout_constraintTop_toBottomOf="@id/labelShort"
app:layout_constraintStart_toStartOf="parent"
android:layout_marginTop="8dp" />
<androidx.constraintlayout.widget.Barrier
android:id="@+id/textBarrier"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:barrierDirection="end" <!-- Barrier a destra delle view elencate -->
app:constraint_referenced_ids="labelShort,labelLong" />
<Button
android:id="@+id/actionButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Azione"
app:layout_constraintTop_toTopOf="@id/labelShort"
app:layout_constraintStart_toEndOf="@id/textBarrier" <!-- sempre dopo il testo più lungo -->
android:layout_marginStart="16dp" />
</androidx.constraintlayout.widget.ConstraintLayout>
Con Barrier e Guideline puoi costruire interfacce responsive che si adattano a schermi, lingue e dimensioni di testo differenti senza dover duplicare i layout XML.
Chains — come distribuire elementi in orizzontale e verticale
Le chain di ConstraintLayout Android permettono di distribuire orizzontalmente o verticalmente un gruppo di view controllando spaziature, allineamenti e pesi. Per creare una chain devi vincolare ogni elemento al precedente e al successivo lungo l’asse della catena.
Chain orizzontale con distribuzione uniforme (spread)
<?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="wrap_content"
android:padding="16dp">
<Button
android:id="@+id/btn_left"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Sinistra"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toStartOf="@id/btn_center" />
<Button
android:id="@+id/btn_center"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Centro"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toEndOf="@id/btn_left"
app:layout_constraintEnd_toStartOf="@id/btn_right" />
<Button
android:id="@+id/btn_right"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Destra"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toEndOf="@id/btn_center"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_chainStyle="spread" /> <!-- stile della chain -->
</androidx.constraintlayout.widget.ConstraintLayout>
Chain verticale con pesi (0dp + layout_constraintVertical_weight)
Usando 0dp come altezza e i pesi verticali puoi distribuire lo spazio disponibile tra le view in modo proporzionale, in maniera simile a LinearLayout ma con più controllo.
<?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">
<TextView
android:id="@+id/section_top"
android:layout_width="0dp"
android:layout_height="0dp"
android:text="Sezione superiore (peso 2)"
android:gravity="center"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toTopOf="@id/section_bottom"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintVertical_chainStyle="spread"
app:layout_constraintVertical_weight="2" />
<TextView
android:id="@+id/section_bottom"
android:layout_width="0dp"
android:layout_height="0dp"
android:text="Sezione inferiore (peso 1)"
android:gravity="center"
app:layout_constraintTop_toBottomOf="@id/section_top"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintVertical_weight="1" />
</androidx.constraintlayout.widget.ConstraintLayout>
Ricorda che le chain supportano anche il bias, permettendoti di spostare l’intero gruppo verso un lato dello schermo mantenendo la proporzione interna tra le view.
ConstraintLayout vs LinearLayout vs RelativeLayout
Quando progett i layout Android puoi scegliere tra diversi container. La tabella seguente confronta ConstraintLayout, LinearLayout e RelativeLayout evidenziando i casi d’uso tipici, le prestazioni e la complessità di manutenzione.
| Layout | Vantaggi principali | Svantaggi | Quando usarlo |
|---|---|---|---|
| ConstraintLayout | Layout complessi in un’unica gerarchia piatta, supporto a chain, barrier, guideline, bias, ottimo per UI responsive | Curva di apprendimento più ripida, XML più verboso | Schermate moderne, layout complessi con molte view, quando vuoi ridurre gli annidamenti |
| LinearLayout | Sintassi semplice, ideale per sequence verticali/orizzontali, leggibile al primo sguardo | Necessita spesso di annidamenti multipli, meno flessibile per posizionamenti complessi | Righe di pulsanti, piccole porzioni di UI, casi in cui la disposizione è puramente lineare |
| RelativeLayout | Permette di posizionare view relativamente ad altre view o al parent | Deprecato in favore di ConstraintLayout, peggiore in termini di performance con annidamenti complessi | Solo per manutenzione di progetti legacy; per nuovo codice preferisci ConstraintLayout |
Per nuove app Android, Google raccomanda di usare principalmente ConstraintLayout insieme a componenti moderni come RecyclerView e MotionLayout, mantenendo LinearLayout per casi semplici e strutture ripetitive.
FAQ su ConstraintLayout Android
Di seguito trovi alcune domande frequenti su ConstraintLayout Android che emergono spesso quando si progettano layout complessi.
1. Quando dovrei usare ConstraintLayout invece di LinearLayout?
Usa ConstraintLayout quando la tua schermata contiene molte view e richiede posizionamenti non puramente lineari (sovrapposizioni, allineamenti incrociati, distribuzioni complesse). Se puoi ottenere il risultato con uno o due LinearLayout annidati, puoi continuare a usare LinearLayout per semplicità; in tutti gli altri casi ConstraintLayout offre prestazioni migliori e una gerarchia più piatta.
2. È obbligatorio impostare gli id alle view in ConstraintLayout?
Non è obbligatorio, ma nella pratica è quasi sempre necessario. Per creare vincoli tra le view usi infatti gli @id/...; senza id diventa difficile gestire catene, barrier e guideline. Assegna sempre un id significativo agli elementi interattivi o a quelli che partecipano a vincoli complessi.
3. Come posso aggiornare dinamicamente i vincoli da Java o Kotlin?
Puoi usare la classe ConstraintSet per definire, clonare e applicare vincoli a runtime. Questo approccio è utile quando vuoi animare transizioni di layout o riutilizzare lo stesso XML con configurazioni diverse.
// Esempio Java con ConstraintSet
ConstraintLayout root = findViewById(R.id.rootConstraint);
ConstraintSet set = new ConstraintSet();
// Clona i vincoli esistenti dal layout XML
set.clone(root);
// Modifica un vincolo: sposta un pulsante sotto un TextView
set.connect(R.id.myButton, ConstraintSet.TOP, R.id.myTextView, ConstraintSet.BOTTOM, 16);
// Applica i nuovi vincoli con animazione opzionale
TransitionManager.beginDelayedTransition(root);
set.applyTo(root);
4. Perché il mio layout con ConstraintLayout non si vede correttamente?
Le cause più comuni sono: vincoli mancanti su almeno un asse (orizzontale o verticale), uso errato di wrap_content dove servirebbe 0dp (match constraints), conflitti tra margini e bias. Verifica sempre nel Layout Inspector di Android Studio che ogni view abbia vincoli chiari lungo entrambi gli assi.
5. Posso annidare più ConstraintLayout uno dentro l’altro?
Sì, tecnicamente è possibile, ma in generale non è consigliato. Uno degli obiettivi di ConstraintLayout è proprio ridurre gli annidamenti. Prima di inserire un ConstraintLayout dentro un altro, verifica se puoi risolvere il problema con un singolo container usando chain, barrier e guideline.
Guide correlate su layout avanzati Android
Se stai approfondendo ConstraintLayout Android, queste guide ti aiutano a padroneggiare altri layout avanzati del framework: