Różnice między ConstraintLayout i RelativeLayout

219

Jestem zdezorientowany co do różnicy między ConstraintLayouti RelativeLayout. Czy ktoś mógłby mi powiedzieć dokładne różnice między nimi?

b2mob
źródło
9
ConstraintLayout jest przeznaczony głównie dla nowych programistów, aby mogli z łatwością projektować układ za pomocą Edytora wizualnego zamiast budować układ ręcznie za pomocą XML.
CopsOnRoad
1
@Jack zdecydowanie ma również głębszy cel dla doświadczonych programistów
Mojżesz Aprico
@MosesAprico masz rację, ma to. Ale myślę deweloperów przyprawione ekspertów już wiele innych sposobów (już wiedzą jak RealtiveLayout, LinearLayout, GridLayoutitd.), Aby uzyskać hierarchię widok chcą.
CopsOnRoad,
5
@CopsOnRoad Właściwie to się mylisz. Apple tworzy układy ograniczeń od ponad 5 lat. Otrzymujesz responsywny projekt do dowolnego rozmiaru i nie musisz pisać wielu skomplikowanych układów. Kiedy zaczynasz wiązać wiele widoków, potrzebujesz tylko 3 podstawowych elementów sterujących, aby stworzyć w pełni responsywny projekt.
Nick Turner

Odpowiedzi:

145

Ma ConstraintLayoutto na celu optymalizację i spłaszczenie hierarchii widoków układów poprzez zastosowanie pewnych reguł do każdego widoku, aby uniknąć zagnieżdżenia.

Reguły przypominają o RelativeLayoutustawieniu na lewo od lewej strony innego widoku.

app:layout_constraintBottom_toBottomOf="@+id/view1"

W przeciwieństwie RelativeLayout, ConstraintLayoutoferty biaswartości, która jest używana do pozycjonowania pogląd w zakresie od 0% do 100% w poziomie i pionie przesunięte względem uchwytów (zaznaczone kółkiem). Te wartości procentowe (i ułamki) zapewniają płynne pozycjonowanie widoku dla różnych gęstości i rozmiarów ekranu.

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

Uchwyt linii bazowej (długa rura z zaokrąglonymi narożnikami, pod uchwytem koła) służy do wyrównania zawartości widoku z innym odniesieniem do widoku.

Kwadratowe uchwyty (w każdym rogu widoku) służą do zmiany rozmiaru widoku w dps.

wprowadź opis zdjęcia tutaj

Jest to całkowicie oparte na opiniach i moje wrażenie ConstraintLayout

Nikola Despotoski
źródło
9
Nadal możemy tworzyć układ spłaszczania za pomocą RelativeLayout, dlatego jestem zdezorientowany, gdy ConstraintLayout zajmuje się tym, gdzie RelativeLayout nie może?
7
RelativeLayout to układ dwuprzebiegowy, podlegający podwójnemu opodatkowaniu. Musi mierzyć / układ co najmniej dwa razy. ConstraintLayout nie ponosi tego ograniczenia wydajności.
Christopher Perry
5
@ Nic Tak, nadal możemy stworzyć układ spłaszczania za pomocą RelativeLayout. Ale oprócz wszystkich wymienionych tutaj ConstraintLayout pozwala używać ujemnych marginesów i widoków podrzędnych rozmiaru w predefiniowanym stosunku . Ostatni to najbardziej niezawodny sposób na utrzymanie proporcji 16: 9 dla ImageView w CardView zgodnie z Material design
Eugene Brusov
4
Istnieje kilka układów, które są niemożliwe w RelativeLayout, chyba że zagnieżdżasz LinearLayout lub inny RelativeLayout. Na przykład: centrowanie „stosu” 3 widoków w pionie względem innego widoku
Gak2
@ Gak2 Nie widzę nic niemożliwego w twoim przykładzie bez zagnieżdżonego układu. Może masz na myśli coś innego z „stosem” niż ja. Używam po prostu „layout_alignEnd”, „layout_below”, „layout _...” i mogę z nim zbudować dowolny stos ...
Niesamowity
81

Równoważne właściwości Układu względnego i Układu ograniczenia

Równoważne właściwości Układu względnego i Układu ograniczenia

(1) Układ względny:

android:layout_centerInParent="true"    

(1) Odpowiednik układu ograniczenia:

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) Układ względny:

android:layout_centerHorizontal="true"

(2) Odpowiednik układu ograniczenia:

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

(3) Układ względny:

android:layout_centerVertical="true"    

(3) Odpowiednik układu ograniczenia:

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

(4) Układ względny:

android:layout_alignParentLeft="true"   

(4) Odpowiednik układu ograniczenia:

app:layout_constraintLeft_toLeftOf="parent"

(5) Układ względny:

android:layout_alignParentStart="true"

(5) Odpowiednik układu ograniczenia:

app:layout_constraintStart_toStartOf="parent"

(6) Układ względny:

android:layout_alignParentRight="true"

(6) Odpowiednik układu ograniczenia:

app:layout_constraintRight_toRightOf="parent"

(7) Układ względny:

android:layout_alignParentEnd="true"    

(7) Odpowiednik układu ograniczenia:

app:layout_constraintEnd_toEndOf="parent"

(8) Układ względny:

android:layout_alignParentTop="true"

(8) Odpowiednik układu ograniczenia:

app:layout_constraintTop_toTopOf="parent"

(9) Układ względny:

android:layout_alignParentBottom="true" 

(9) Odpowiednik układu ograniczenia:

app:layout_constraintBottom_toBottomOf="parent"

(10) Układ względny:

android:layout_alignStart="@id/view"

(10) Odpowiednik układu ograniczenia:

app:layout_constraintStart_toStartOf="@id/view"

(11) Układ względny:

android:layout_alignLeft="@id/view" 

(11) Odpowiednik układu ograniczenia:

app:layout_constraintLeft_toLeftOf="@id/view"

(12) Układ względny:

android:layout_alignEnd="@id/view"  

(12) Odpowiednik układu ograniczenia:

app:layout_constraintEnd_toEndOf="@id/view"

(13) Układ względny:

android:layout_alignRight="@id/view"

(13) Odpowiednik układu ograniczenia:

app:layout_constraintRight_toRightOf="@id/view"

(14) Układ względny:

android:layout_alignTop="@id/view"  

(14) Odpowiednik układu ograniczenia:

app:layout_constraintTop_toTopOf="@id/view"

(15) Układ względny:

android:layout_alignBaseline="@id/view" 

(15) Odpowiednik układu ograniczenia:

app:layout_constraintBaseline_toBaselineOf="@id/view"

(16) Układ względny:

android:layout_alignBottom="@id/view"

(16) Odpowiednik układu ograniczenia:

app:layout_constraintBottom_toBottomOf="@id/view"

(17) Układ względny:

android:layout_toStartOf="@id/view"

(17) Odpowiednik układu ograniczenia:

app:layout_constraintEnd_toStartOf="@id/view"

(18) Układ względny:

android:layout_toLeftOf="@id/view"  

(18) Odpowiednik układu ograniczenia:

app:layout_constraintRight_toLeftOf="@id/view"

(19) Układ względny:

android:layout_toEndOf="@id/view"

(19) Odpowiednik układu ograniczenia:

app:layout_constraintStart_toEndOf="@id/view"

(20) Układ względny:

android:layout_toRightOf="@id/view"

(20) Odpowiednik układu ograniczenia:

app:layout_constraintLeft_toRightOf="@id/view"

(21) Układ względny:

android:layout_above="@id/view" 

(21) Odpowiednik układu ograniczenia:

app:layout_constraintBottom_toTopOf="@id/view"

(22) Układ względny:

android:layout_below="@id/view" 

(22) Odpowiednik układu ograniczenia:

app:layout_constraintTop_toBottomOf="@id/view"

Naimatullah
źródło
2
Czy możesz publikować jako tekst zamiast obrazu? Tak, że będzie to bardzo przydatne dla mnie, a także dla innych w przyszłości.
Nowy programista,
3
Każdy, kto zaczyna się uczyć układów wiązań, musi to zobaczyć. Dzięki.
grantespo
1
Jest to użyteczna informacja, ale jest to po prostu zrzut dokumentacji i nie robi nic, aby wyjaśnić różnicę między nimi.
YetAnotherRandomUser
1
Nie, nie mam czasu na przeglądanie dokumentów, jest to z pewnością przydatne. I napisane prostym językiem. Upvoting.
CodeToLife,
46

Zgłoszone przez wydajność @davidpbr ConstraintLayout

Zrobiłem dwa podobne układy 7 dzieci, każdy z rodzicem ConstraintLayouti RelativeLayout. Na podstawie narzędzia śledzenia metody Android Studio wydaje się, że ConstraintLayoutspędza więcej czasu w onMeasure i wykonuje dodatkową pracę onFinishInflate.

Wykorzystana biblioteka ( support-v4, appcompat-v7…):

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

Wersje urządzeń / Androida odtworzone na: Samsung Galaxy S6 (SM-G920A. Przepraszamy, brak bankomatu Nexus). Android 5.0.2

Szybkie porównanie śledzenia metody:

1

Przykładowe repozytorium Github: https://github.com/OnlyInAmerica/ConstraintLayoutPerf

Dhaval Jivani
źródło
z tego samego problemu: na razie zamierzam to zamknąć - alfa 4/5 przyniosło sporo poprawy wydajności. Prawdopodobnie będziemy w stanie poprawić to bardziej, ale może to poczekać od wersji 1.0.
Oleksandr
Czy możesz wyjaśnić, jakiego narzędzia użyłeś, aby stworzyć to świetne porównanie?
Nativ
2
@Nativ Monotirs-> CPU-> Ikona śledzenia czasu
Andrey T
18
Uruchom i profiluj ten sam kod z układem ograniczeń: 1.0.1 na Nexusie 5 z Androidem 6.0.1, oto wyniki: Układ względny - init 2ms przy pomiarze 30ms + 16ms = 62ms przy Layouyt 7ms = 9ms razem 54 ms Układ ograniczenia - init Układ ograniczenia 7ms generuje parametry układu + dodaj widok ~ 7 * 2ms = 14ms Przy pomiarze 60ms + 52ms ~ 112ms Przy układzie 8ms łącznie ~ 141ms Pierwsza inicjalizacja układu względnego prawie trzy razy szybciej niż ograniczenie.
Andrey T
2
Wprowadzono układ ograniczeń, aby zredukować hierarchię widoków zagnieżdżonych. Zatem mniejsza hierarchia oznacza mniej czasu na przechodzenie od góry do dołu w drzewie widoku. Więc po co tworzyć hierarchię widoków zagnieżdżonych, która może nie być potrzebna w układzie ograniczeń i porównywać ją z układem względnym, w którym masz większe szanse na uzyskanie struktury zagnieżdżonej?
codepeaker
27

Oto różnice / zalety:

  1. Układ ograniczeń ma podwójną moc zarówno Układu względnego, jak i Układu liniowego: Ustaw względne położenia widoków (jak Układ względny), a także ustaw wagi dla dynamicznego interfejsu użytkownika (co było możliwe tylko w Układzie liniowym).

  2. Bardzo potężnym zastosowaniem jest grupowanie elementów poprzez tworzenie łańcucha. W ten sposób możemy utworzyć grupę widoków, która jako całość może być umieszczona w pożądany sposób bez dodawania kolejnej warstwy hierarchii tylko w celu utworzenia innej grupy widoków.

  3. Oprócz obciążeń możemy zastosować odchylenie poziome i pionowe, które jest niczym innym jak procentem przesunięcia od środka. (odchylenie 0,5 oznacza wyrównanie centralne. Każda wartość mniejsza lub większa oznacza odpowiedni ruch w odpowiednim kierunku).

  4. Inną bardzo ważną cechą jest to, że szanuje i zapewnia funkcjonalność do obsługi widoków GONE, dzięki czemu układy nie ulegają uszkodzeniu, jeśli jakiś widok jest ustawiony na GONE za pomocą kodu Java. Więcej można znaleźć tutaj: https://developer.android.com/reference/android/support/constraint/ConstraintLayout.html#VisibilityBehavior

  5. Zapewnia moc automatycznego stosowania ograniczeń dzięki narzędziu Blue print i Visual Editor, które ułatwia projektowanie strony.

Wszystkie te funkcje prowadzą do spłaszczenia hierarchii widoku, co poprawia wydajność, a także pomaga w tworzeniu responsywnego i dynamicznego interfejsu użytkownika, który można łatwiej dostosować do różnych rozmiarów i gęstości ekranu.

Oto najlepsze miejsce do szybkiego uczenia się: https://codelabs.developers.google.com/codelabs/constraint-layout/#0

Vishu Gupta
źródło
6) ConstraintLayout umożliwia zmianę rozmiarów widoków podrzędnych w predefiniowanych proporcjach medium.com/google-developers/… . Przydałby się na przykład, gdy zamierzasz zachować ImageView w formacie 16: 9.
Eugene Brusov
15

Duża różnica polega na tym, że ConstraintLayout szanuje ograniczenia, nawet jeśli widok zniknie. Więc nie złamie układu, jeśli masz łańcuch i chcesz sprawić, że widok zniknie na środku.

Herrbert74
źródło
czy możesz podać mi jakiś przykład? Załóżmy, że są tam 3 przyciski. Ukryję drugi przycisk, a trzeci przycisk zostanie dołączony do drugiego przycisku o identyfikatorze jako btn2. Załóżmy, że ukrywam drugi przycisk, a następnie, w jaki sposób trzeci przycisk może znaleźć identyfikator drugiego przycisku?
1
To nieprawda. Jeśli ustawisz widoczność przycisku jako „NIEWIDZIALNY” zamiast „BRAK”, nie złamiesz ograniczeń. Jeśli chodzi o mnie, największą różnicą, jak powiedział @Nikola, jest stronniczość, która pomaga tworzyć więcej „responsywnych” widoków.
zapotec
@ Nic Załóżmy, że przyciski są pod sobą. Nawet jeśli ukryjesz tButton 2, nadal znajduje się on w „umowie widoku”, w twoim pliku xml lub w kodzie. ConstraintLayout będzie go przestrzegać, a przycisk 3 znajdzie się pod przyciskiem 1. W RelativeLayout zniknął przycisk 2, wraz z nim zniknęło ograniczenie, więc przycisk 3 będzie w domyślnej pozycji, więc u góry po lewej stronie ekranu.
Herrbert74
@zapotec Szanuję, że inne rzeczy są dla ciebie ważniejsze, ale dla mnie to naprawdę fajna różnica. Naprawia jedyną rzecz, której nienawidziłem w RelativeLayout. Używanie niewidocznego nie jest opcją, ponieważ zajmie miejsce.
Herrbert74
7

Oprócz odpowiedzi @ dhaval-jivani.

Zaktualizowałem projekt github projektu do najnowszej wersji układu ograniczeń v.1.1.0-beta3

Zmierzyłem i porównałem czas metody onCreate i czas między początkiem onCreate a końcem wykonania ostatniej metody preformDraw, która jest widoczna na monitorze CPU. Wszystkie testy zostały wykonane na Samsung S5 mini z Androidem 6.0.1 Oto wyniki:

Świeży start (pierwsze otwarcie ekranu po uruchomieniu aplikacji)

Układ względny

OnCreate: 123ms

Ostatni preformDraw czas - OnCreate czas: 311,3 ms

Układ ograniczeń

OnCreate: 120,3 ms

Ostatni preformDraw czas - OnCreate czas: 310ms

Poza tym sprawdziłem test wydajności z tego artykułu , tutaj kod i stwierdziłem, że w pętli zlicza mniej niż 100 wariant układu ograniczenia jest szybszy podczas wykonywania nadmuchiwania, pomiaru i układu niż warianty z układem względnym. A na starych urządzeniach z Androidem, takich jak Samsung S3 z Androidem 4.3, różnica jest większa.

Podsumowując, zgadzam się z komentarzami z artykułu :

Czy warto refaktoryzować stare widoki, aby włączyć je z RelativeLayout lub LinearLayout?

Jak zawsze: zależy 🙂

Nie zmieniłbym niczego, chyba że masz problem z wydajnością w bieżącej hierarchii układu lub chcesz wprowadzić znaczące zmiany w układzie. Chociaż ostatnio tego nie mierzyłem, nie znalazłem żadnych problemów z wydajnością w ostatnich wydaniach. Myślę więc, że powinieneś być bezpieczny w użyciu. ale - jak już powiedziałem - nie migrujcie tylko ze względu na migrację. Rób to tylko wtedy, gdy jest taka potrzeba i skorzystaj z niej. Jednak w przypadku nowych układów prawie zawsze używam ConstraintLayout. O wiele lepiej porównać do tego, co mieliśmy wcześniej.

Andrey T.
źródło
6

Oficjalnie ConstraintLayoutjest znacznie szybszy

W wydaniu N Androida ConstraintLayoutklasa zapewnia podobną funkcjonalność RelativeLayout, ale znacznie niższą cenę.

serv-inc
źródło
6

Prawdziwe pytanie, jakie należy zadać, to: czy istnieje jakiś powód, aby używać innego układu niż układ z ograniczeniami? Myślę, że odpowiedź może być przecząca.

Ci, którzy twierdzą, że są skierowani do początkujących programistów lub tym podobnych, powinni podać jakiś powód, aby byli gorsi od jakiegokolwiek innego układu.

Układy ograniczeń są lepsze pod każdym względem (kosztują jak 150 KB w rozmiarze APK). Są szybsze, łatwiejsze, bardziej elastyczne, lepiej reagują na zmiany, naprawiają problemy, gdy przedmioty znikają, lepiej dostosowują się do radykalnie różnych typów ekranów i nie używają wiązki zagnieżdżonej o tak długim czasie narysowana struktura drzewa na wszystko. Możesz umieścić wszystko w dowolnym miejscu, w odniesieniu do wszystkiego, w dowolnym miejscu.

Byli nieco zaniedbani w połowie 2016 roku, gdzie edytor układu wizualnego po prostu nie był wystarczająco dobry, ale do tego stopnia, że ​​jeśli masz układ, możesz poważnie rozważyć zastosowanie układu ograniczenia, nawet gdy robi to samo RelativeLayout, a nawet proste LinearLayout. FrameLayoutsnajwyraźniej nadal mają swój cel. Ale w tym momencie nie widzę budowania niczego innego. Gdyby zaczęli od tego, nie dodaliby nic więcej.

Tatarize
źródło
1
Czy jest jakiś dowód na to, że jest szybszy?
Rajesh Nasit
1
Tak. To jest szybsze. Układ jest zapisany w jednym rozwiązaniu zamiast iteracji przez drzewo. W przypadku większości rzeczy nie będzie to miało znaczenia, ponieważ odbywa się to przy wywołaniu układu. Ale drzewo widoku jest łatwe, ale tworzy wiele widoków wewnątrz widoków, które wymagają połączeń wymagających połączeń. Choć teoretycznie jest to ładniejsze, w praktyce wykonanie układu w jednym kawałku kodu jest znacznie łatwiejsze niż iteracja w całym drzewie widoku.
Zrobiłoby
Mam do czynienia z innym pytaniem: czy powinienem zastąpić wszystkie istniejące Relativelayouts w aplikacji, nad którą pracuję? Czy to znacznie poprawi wydajność?
Sreekanth Karumanaghat
@SreekanthKarumanaghat wygląda na to, że nigdy nie cofniesz czasu potrzebnego na zastąpienie tych z powrotem w czasie przełączania, by cię uratować. Mówimy o cyklach 3,5 ms spadających do 3,25 ms w większości przypadków. Jeśli daje ci dodatkową funkcję lub coś, czego potrzebujesz, to na pewno, ale wyłącznie ze względu na szybkość nie. Chociaż mówimy o naciśnięciu przycisku konwersji.
Tatarize
5

Wniosek, który mogę wyciągnąć, jest

1) Możemy zaprojektować interfejs użytkownika bez dotykania części kodu xml , szczerze mówiąc, czuję, że Google skopiował sposób projektowania interfejsu użytkownika w aplikacjach na iOS , będzie to sensowne, jeśli znasz się na tworzeniu interfejsu w iOS, ale we względnym układzie jego ciężko ustawić ograniczenia bez dotykania projektu xml .

2) Po drugie, ma płaską hierarchię widoku w przeciwieństwie do innych układów, więc ma lepszą wydajność niż układ względny, który można zobaczyć z innych odpowiedzi

3) Ma także dodatkowe rzeczy oprócz tego, co ma układ względny, takie jak kołowe pozycjonowanie względne, w którym możemy ustawić inny widok względem tego w określonym promieniu pod pewnym kątem, który nie może zrobić w układzie względnym

Mówię to jeszcze raz: projektowanie interfejsu użytkownika za pomocą układu ograniczeń jest takie samo jak projektowanie interfejsu użytkownika w iOS, więc w przyszłości, jeśli będziesz pracować na iOS, łatwiej ci będzie, jeśli użyjesz układu ograniczeń

Murali Krish
źródło
1

Jedyną różnicą, którą zauważyłem, jest to, że rzeczy ustawione we względnym układzie za pomocą przeciągania i upuszczania automatycznie mają swoje wymiary względem innych elementów, więc po uruchomieniu aplikacji otrzymujesz to, co widzisz. Jednak w układzie ograniczenia nawet po przeciągnięciu i upuszczeniu elementu w widoku projektu po uruchomieniu aplikacji rzeczy mogą się zmieniać. Można to łatwo naprawić, ręcznie ustawiając ograniczenia lub, bardziej ryzykownym ruchem jest kliknięcie prawym przyciskiem myszy elementu w drzewie komponentów, wybranie podmenu układu ograniczenia, a następnie kliknięcie „wnioskuj ograniczenia”. Mam nadzieję że to pomoże

Wilson
źródło