Differenze tra ConstraintLayout e RelativeLayout


219

Sono confuso sulla differenza tra ConstraintLayoute RelativeLayout. Qualcuno potrebbe dirmi le esatte differenze tra loro?


9
ConstraintLayout è progettato principalmente per i nuovi programmatori in modo che possano facilmente progettare il layout utilizzando Visual Editor invece di costruirlo manualmente con XML.
CopsOnadad

1
@Jack sicuramente ha anche uno scopo più profondo per gli esperti esperti
Moses Aprico,

@MosesAprico hai ragione, ce l'ha. Ma penso che gli sviluppatori esperti condito già hanno molti altri modi (che già conoscono come RealtiveLayout, LinearLayout, GridLayoutetc.) per ottenere la gerarchia della vista che vogliono.
CopsOnRoad,

5
@CopsOnRoad In realtà ti sbagli. Apple ha fatto layout di vincoli per oltre 5 anni. Ottieni un design reattivo a qualsiasi dimensione e non devi scrivere un sacco di layout complessi. Quando si avvia l'associazione di più viste, sono necessari solo 3 controlli di base per creare un design completamente reattivo.
Nick Turner,

Risposte:


145

L'intenzione ConstraintLayoutè quella di ottimizzare e appiattire la gerarchia della vista dei layout applicando alcune regole a ciascuna vista per evitare l'annidamento.

Le regole ti ricordano RelativeLayout, ad esempio impostando la sinistra a sinistra di un'altra vista.

app:layout_constraintBottom_toBottomOf="@+id/view1"

Diversamente RelativeLayout, ConstraintLayoutoffre un biasvalore utilizzato per posizionare una vista in termini di offset orizzontale e verticale dello 0% e del 100% rispetto alle maniglie (contrassegnate da un cerchio). Queste percentuali (e frazioni) offrono un posizionamento uniforme della vista su diverse densità e dimensioni dello schermo.

app:layout_constraintHorizontal_bias="0.33" <!-- from 0.0 to 1.0 -->
app:layout_constraintVertical_bias="0.53" <!-- from 0.0 to 1.0 -->

La maniglia della linea di base (tubo lungo con angoli arrotondati, sotto la maniglia del cerchio) viene utilizzata per allineare il contenuto della vista con un altro riferimento della vista.

Le maniglie quadrate (su ogni angolo della vista) vengono utilizzate per ridimensionare la vista in dps.

inserisci qui la descrizione dell'immagine

Questo è totalmente basato sull'opinione e la mia impressione di ConstraintLayout


9
Possiamo ancora creare un layout piatto usando RelativeLayout, ecco perché sono confuso dove ConstraintLayout si preoccupa dove RelativeLayout non può?

7
RelativeLayout è un layout a due passaggi, che soffre di doppia tassazione. Deve misurare / layout almeno due volte. ConstraintLayout non subisce questa penalità di prestazione.
Christopher Perry,

5
@Niente Sì, possiamo ancora creare layout appiattiti usando RelativeLayout. Ma oltre a tutti quelli qui menzionati, ConstraintLayout ti consente di utilizzare margini negativi e dimensioni sottoview in rapporto predefinito . L'ultimo è il modo più robusto per mantenere il rapporto 16: 9 per ImageView in CardView in conformità con il design del materiale
Eugene Brusov,

4
Esistono alcuni layout impossibili in RelativeLayout a meno che non si annidi un LinearLayout o un altro RelativeLayout. Ad esempio: centrare uno "stack" di 3 viste verticalmente rispetto a un'altra vista
Gak2

@ Gak2 Non riesco a vedere nulla di impossibile nel tuo esempio senza un layout nidificato. Forse vuoi dire qualcos'altro con "stack" di me. Uso semplicemente "layout_alignEnd", "layout_below", "layout _..." e posso creare qualsiasi tipo di stack con esso ...
L'incredibile

81

Proprietà equivalenti Layout relativo e Layout vincolo

Proprietà equivalenti Layout relativo e Layout vincolo

(1) Layout relativo:

android:layout_centerInParent="true"    

(1) Equivalente layout vincolo:

app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"

(2) Layout relativo:

android:layout_centerHorizontal="true"

(2) Equivalente layout vincolo:

app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintEnd_toEndOf="parent"

(3) Layout relativo:

android:layout_centerVertical="true"    

(3) Equivalente layout vincolo:

app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toTopOf="parent"

(4) Layout relativo:

android:layout_alignParentLeft="true"   

(4) Equivalente layout vincolo:

app:layout_constraintLeft_toLeftOf="parent"

(5) Layout relativo:

android:layout_alignParentStart="true"

(5) Equivalente layout vincolo:

app:layout_constraintStart_toStartOf="parent"

(6) Layout relativo:

android:layout_alignParentRight="true"

(6) Equivalente layout vincolo:

app:layout_constraintRight_toRightOf="parent"

(7) Layout relativo:

android:layout_alignParentEnd="true"    

(7) Equivalente layout vincolo:

app:layout_constraintEnd_toEndOf="parent"

(8) Layout relativo:

android:layout_alignParentTop="true"

(8) Equivalente layout vincolo:

app:layout_constraintTop_toTopOf="parent"

(9) Layout relativo:

android:layout_alignParentBottom="true" 

(9) Equivalente layout vincolo:

app:layout_constraintBottom_toBottomOf="parent"

(10) Layout relativo:

android:layout_alignStart="@id/view"

(10) Equivalente layout vincolo:

app:layout_constraintStart_toStartOf="@id/view"

(11) Layout relativo:

android:layout_alignLeft="@id/view" 

(11) Equivalente layout vincolo:

app:layout_constraintLeft_toLeftOf="@id/view"

(12) Layout relativo:

android:layout_alignEnd="@id/view"  

(12) Equivalente layout vincolo:

app:layout_constraintEnd_toEndOf="@id/view"

(13) Layout relativo:

android:layout_alignRight="@id/view"

(13) Equivalente layout vincolo:

app:layout_constraintRight_toRightOf="@id/view"

(14) Layout relativo:

android:layout_alignTop="@id/view"  

(14) Equivalente layout vincolo:

app:layout_constraintTop_toTopOf="@id/view"

(15) Layout relativo:

android:layout_alignBaseline="@id/view" 

(15) Equivalente layout vincolo:

app:layout_constraintBaseline_toBaselineOf="@id/view"

(16) Layout relativo:

android:layout_alignBottom="@id/view"

(16) Equivalente layout vincolo:

app:layout_constraintBottom_toBottomOf="@id/view"

(17) Layout relativo:

android:layout_toStartOf="@id/view"

(17) Equivalente layout vincolo:

app:layout_constraintEnd_toStartOf="@id/view"

(18) Layout relativo:

android:layout_toLeftOf="@id/view"  

(18) Equivalente layout vincolo:

app:layout_constraintRight_toLeftOf="@id/view"

(19) Layout relativo:

android:layout_toEndOf="@id/view"

(19) Equivalente layout vincolo:

app:layout_constraintStart_toEndOf="@id/view"

(20) Layout relativo:

android:layout_toRightOf="@id/view"

(20) Equivalente layout vincolo:

app:layout_constraintLeft_toRightOf="@id/view"

(21) Layout relativo:

android:layout_above="@id/view" 

(21) Equivalente layout vincolo:

app:layout_constraintBottom_toTopOf="@id/view"

(22) Layout relativo:

android:layout_below="@id/view" 

(22) Equivalente layout vincolo:

app:layout_constraintTop_toBottomOf="@id/view"


2
Puoi pubblicare come testo anziché come immagine? In modo che sia molto utile per me e anche per gli altri in futuro.
Nuovo sviluppatore,

3
Tutti quelli che iniziano a imparare i layout dei vincoli devono vederlo. Grazie.
grantespo,

1
Si tratta di informazioni utili, ma è semplicemente un dump della documentazione e non fa nulla per spiegare la differenza tra di loro.
YetAnotherRandomUser

1
No, non ho tempo di consultare i documenti, questo è sicuramente utile. E scritto in un linguaggio semplice. Upvoting.
CodeToLife,

46

Segnalato dalle prestazioni di @davidpbr ConstraintLayout

Ho realizzato due layout di 7 figli simili, uno ciascuno con un genitore ConstraintLayoute RelativeLayout. Basato sullo strumento di tracciamento dei metodi di Android Studio, sembra che ConstraintLayoutpassi più tempo in onMeasure ed esegua lavori aggiuntivi in onFinishInflate.

Libreria utilizzata ( support-v4, appcompat-v7...):

com.android.support.constraint:constraint-layout:1.0.0-alpha1

Dispositivi / versioni Android riprodotte su: Samsung Galaxy S6 (SM-G920A. Siamo spiacenti, nessun Nexus atm). Android 5.0.2

Confronto di traccia rapida del metodo:

1

Esempio di repository Github: https://github.com/OnlyInAmerica/ConstraintLayoutPerf


dallo stesso problema: sto per chiudere questo per ora - alpha 4/5 ha apportato un bel po 'di miglioramento delle prestazioni. Probabilmente saremo in grado di migliorarlo di più, ma ciò potrebbe attendere post 1.0.
Oleksandr,

Puoi spiegarci quale strumento hai usato per creare questo grande confronto?
Nativ

2
@Nativ Monotirs-> CPU-> Icona Time tracker
Andrey T

18
Esegui e profila lo stesso codice con layout di vincolo: 1.0.1 su Nexus 5 con Android 6.0.1, qui risultati: Layout relativo - init 2ms su Misura 30ms + 16ms = 62ms su Layouyt 7ms = 9ms totali 54 ms Layout del vincolo - init 7ms Layout del vincolo genera parametri di layout + aggiungi vista ~ 7 * 2ms = 14ms On Misura 60ms + 52ms ~ 112ms On Layout 8ms totali ~ 141ms Prima inizializzazione del layout Relativo quasi tre volte più veloce di Vincolo.
Andrey T

2
Il layout del vincolo viene introdotto in modo da ridurre la gerarchia della vista nidificata. Quindi, Meno gerarchia significa meno tempo per attraversare dall'alto verso il basso nella struttura ad albero della vista. Quindi, qual è il punto per creare una gerarchia di viste nidificate che potrebbe non essere necessaria nel layout dei vincoli e confrontarla con il layout relativo in cui hai più possibilità di finire con una struttura nidificata?
codepeaker dal

27

Di seguito sono le differenze / vantaggi:

  1. Il layout del vincolo ha una doppia potenza sia del layout relativo che del layout lineare: imposta le posizioni relative delle viste (come il layout relativo) e imposta anche i pesi per l'interfaccia utente dinamica (che era possibile solo nel layout lineare).

  2. Un uso molto potente è il raggruppamento di elementi formando una catena. In questo modo possiamo formare un gruppo di viste che nel loro insieme possono essere posizionate nel modo desiderato senza aggiungere un altro livello di gerarchia solo per formare un altro gruppo di viste.

  3. Oltre ai pesi, possiamo applicare la polarizzazione orizzontale e verticale che non è altro che la percentuale di spostamento dal centro. (polarizzazione di 0,5 significa allineato centralmente. Qualsiasi valore inferiore o superiore indica un movimento corrispondente nella rispettiva direzione).

  4. Un'altra caratteristica molto importante è che rispetta e fornisce la funzionalità per gestire le viste GONE in modo che i layout non si rompano se alcune viste sono impostate su GONE tramite codice java. Altre informazioni sono disponibili qui: https://developer.android.com/reference/android/support/constraint/ConstraintLayout.html#VisibilityBehavior

  5. Fornisce la potenza del vincolo automatico applicato dall'uso di Blue Print e Visual Editor che semplifica la progettazione di una pagina.

Tutte queste funzionalità portano all'appiattimento della gerarchia della vista che migliora le prestazioni e aiuta anche a rendere l'interfaccia utente reattiva e dinamica che può adattarsi più facilmente alle diverse dimensioni e densità dello schermo.

Ecco il posto migliore per imparare rapidamente: https://codelabs.developers.google.com/codelabs/constraint-layout/#0


6) ConstraintLayout consente di dimensionare le visualizzazioni secondarie in rapporti predefiniti medium.com/google-developers/… . Sarebbe utile ad esempio quando hai intenzione di mantenere ImageView in 16: 9.
Eugene Brusov,

15

Una grande differenza è che ConstraintLayout rispetta i vincoli anche se la vista è sparita. Quindi non romperà il layout se hai una catena e vuoi far sparire una vista nel mezzo.


puoi darmi qualche esempio? supponiamo che ci siano 3 pulsanti. Nasconderò il 2o pulsante e il 3o pulsante verrà collegato al 2o pulsante con l'id come btn2. Supponiamo che nasconda il 2 ° pulsante, quindi come il 3 ° pulsante potrebbe trovare l'id del 2 ° pulsante?

1
Non è vero. Se si imposta la visibilità di un pulsante come "INVISIBILE" anziché "GONE" non si romperanno i vincoli. Per quanto mi riguarda, la più grande differenza come ha detto @Nikola è la tendenza che ti aiuta a creare viste più "reattive".
zapotec,

@Niente Supponiamo che i pulsanti siano uno sotto l'altro. Anche se nascondi tButton 2, è ancora presente nel "contratto vista", nel tuo XML o codice. ConstraintLayout lo rispetterà e il pulsante 3 si troverà sotto il pulsante 1. In un RelativeLayout il pulsante 2 è sparito, il contrappeso è andato con esso, quindi il pulsante 3 sarà nella posizione predefinita, quindi in alto a sinistra dello schermo.
Herrbert74,

@zapotec Rispetto che altre cose siano più importanti per te, ma per me questa è davvero una bella differenza. Risolve l'unica cosa che odiavo in RelativeLayout. L'uso di invisible non è un'opzione, perché rivendicherà lo spazio.
Herrbert74,

7

Oltre alla risposta @ dhaval-jivani.

Ho aggiornato il progetto github del progetto all'ultima versione del layout dei vincoli v.1.1.0-beta3

Ho misurato e confrontato il tempo del metodo onCreate e il tempo tra l'inizio di onCreate e la fine dell'esecuzione dell'ultimo metodo preformDraw che è visibile nel monitor della CPU. Tutti i test sono stati eseguiti su Samsung S5 mini con Android 6.0.1 Qui i risultati:

Nuovo avvio (prima apertura dello schermo dopo l'avvio dell'applicazione)

Layout relativo

OnCreate: 123ms

Ultima preforma Tempo di disegno - Tempo di creazione: 311,3 ms

Layout dei vincoli

OnCreate: 120.3ms

Ultima preforma Tempo di disegno - Tempo di creazione: 310 ms

Oltre a ciò, ho verificato il test delle prestazioni di questo articolo , qui il codice e ho scoperto che su loop conta meno di 100 varianti di layout di vincolo è più veloce durante l'esecuzione di gonfiaggio, misura e layout, quindi varianti con Layout relativo. E sui vecchi dispositivi Android, come Samsung S3 con Android 4.3, la differenza è maggiore.

In conclusione, sono d'accordo con i commenti dell'articolo :

Vale la pena di refactoring le vecchie viste attivarlo da RelativeLayout o LinearLayout?

Come sempre: dipende 🙂

Non farei alcun refactoring a meno che tu non abbia un problema di prestazioni con la tua attuale gerarchia di layout o desideri comunque apportare modifiche significative al layout. Anche se non l'ho misurato di recente, non ho riscontrato problemi di prestazioni nelle ultime versioni. Quindi penso che dovresti essere sicuro di usarlo. ma - come ho già detto - non solo migrare per motivi di migrazione. Fallo solo se ce n'è bisogno e ne trai beneficio. Per i nuovi layout, tuttavia, utilizzo quasi sempre ConstraintLayout. È molto meglio rispetto a quello che avevamo prima.


6

Ufficialmente, ConstraintLayoutè molto più veloce

Nella versione N di Android, la ConstraintLayoutclasse offre funzionalità simili a RelativeLayout, ma a un costo significativamente inferiore.


6

La vera domanda da porsi è: c'è qualche motivo per usare un layout diverso da un layout di vincolo? Credo che la risposta potrebbe essere no.

A coloro che insistono sul fatto che sono rivolti a programmatori principianti o simili, dovrebbero fornire qualche motivo per essere inferiori a qualsiasi altro layout.

I layout dei vincoli sono migliori in ogni modo (costano circa 150.000 in dimensioni APK.). Sono più veloci, sono più facili, sono più flessibili, reagiscono meglio ai cambiamenti, risolvono i problemi quando gli oggetti vanno via, si conformano meglio a tipi di schermo radicalmente diversi e non usano un mucchio di loop nidificati con così tanto tempo struttura ad albero disegnata per tutto. Puoi mettere qualsiasi cosa ovunque, rispetto a qualsiasi cosa, ovunque.

Erano un po 'fuori di testa a metà 2016, dove l'editor del layout visivo non era abbastanza buono, ma sono al punto che se hai un layout, potresti prendere in seria considerazione l'uso di un layout di vincolo, anche quando fa la stessa cosa di un RelativeLayout, o anche di un semplice LinearLayout. FrameLayoutschiaramente hanno ancora il loro scopo. Ma non riesco a vedere nient'altro a questo punto. Se avessero iniziato con questo non avrebbero aggiunto nient'altro.


1
C'è qualche prova più veloce?
Rajesh Nasit,

1
Sì. È più veloce. Il layout è inattivo in un singolo solutore anziché scorrere in un albero. Per la maggior parte delle cose non importa perché è fatto alla chiamata al layout. Ma la cosa dell'albero delle viste, sebbene semplice, crea un mucchio di viste all'interno delle viste che richiedono chiamate che richiedono chiamate. Sebbene teoricamente sia più bello, in pratica eseguire il layout in un bit di codice è molto più semplice che scorrere l'intero albero della vista. Sarebbe più impressionante con più visualizzazioni, ma ecco un punto di riferimento di maggio: medium.com/@krpiotrek/constraintlayout-performance-c1455c7984d7
Tatarize

Sto affrontando un'altra domanda, devo sostituire tutti i Relativelayout esistenti nell'app su cui sto lavorando? Migliorerà significativamente le prestazioni?
Sreekanth Karumanaghat,

@SreekanthKarumanaghat sembra che non avresti mai recuperato il tempo necessario per rimpiazzarli nel tempo che ti avrebbe risparmiato. Stiamo parlando di cicli da 3,5 ms che scendono a 3,25 ms nella maggior parte dei casi. Se ti dà una funzionalità extra o qualcosa di cui hai bisogno, allora certo, ma per motivi di velocità, nah. Anche se stiamo parlando premendo un pulsante di conversione.
Tatarize il

5

La conclusione che posso fare è

1) Possiamo progettare l'interfaccia utente senza toccare la parte xml del codice, a dire il vero penso che Google abbia copiato il modo in cui l'interfaccia utente è progettata nelle app iOS , avrà senso se hai familiarità con lo sviluppo dell'interfaccia utente in iOS, ma nel relativo layout è difficile impostare i vincoli senza toccare il design XML .

2) In secondo luogo ha una gerarchia di visualizzazione piatta a differenza di altri layout, quindi offre prestazioni migliori rispetto al layout relativo che potresti aver visto da altre risposte

3) Ha anche cose extra oltre a ciò che ha il layout relativo, come il posizionamento relativo circolare in cui possiamo posizionare un'altra vista rispetto a questa a un certo raggio con un certo angolo che non può fare nel layout relativo

Lo dico di nuovo, progettare l'interfaccia utente usando il layout dei vincoli è lo stesso che progettare l'interfaccia utente in iOS, quindi in futuro se lavori su iOS lo troverai più facile se hai usato il layout dei vincoli


1

L'unica differenza che ho notato è che le cose impostate in un layout relativo tramite trascinamento della selezione hanno automaticamente le loro dimensioni rispetto ad altri elementi dedotti, quindi quando esegui l'app ciò che vedi è ciò che ottieni. Tuttavia, nel layout del vincolo anche se si trascina e rilascia un elemento nella vista di progettazione, quando si esegue l'app le cose potrebbero essere spostate. Questo può essere facilmente risolto impostando manualmente i vincoli o, una mossa più rischiosa è fare clic con il tasto destro del mouse sull'albero dei componenti, selezionando il sottomenu di layout dei vincoli, quindi facendo clic su "infera vincoli". Spero che questo ti aiuti

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.