Відмінності між ConstraintLayout і RelativeLayout


219

Мене бентежить різниця між ConstraintLayoutі RelativeLayout. Може хтось, будь ласка, скажіть мені точні відмінності між ними?


9
ConstraintLayout розроблений в основному для нових програмістів, щоб вони могли легко спроектувати макет за допомогою Visual Editor, а не будувати макет вручну через XML.
CopsOnRoad

1
@Jack, безумовно, також має більш глибоке призначення для досвідчених розробників
Мойсей Апріко

@MosesAprico ти маєш рацію. Але я думаю , заправлений експерт деви вже є багато інших способів (вони вже знають , як RealtiveLayout, LinearLayout, і GridLayoutт.д.) , щоб отримати ієрархію вид , що вони хочуть.
CopsOnRoad

5
@CopsOnRoad Насправді ви помиляєтесь. Apple займається плануванням обмежень протягом 5+ років. Ви отримуєте чуйний дизайн до будь-якого розміру і не потрібно писати багато складних макетів. Коли ви починаєте прив'язувати кілька переглядів, вам знадобляться лише 3 основних елементи управління, щоб створити повністю чуйний дизайн.
Нік Тернер

Відповіді:


145

Намір ConstraintLayoutполягає в оптимізації та вирівнюванні ієрархії перегляду своїх макетів, застосовуючи деякі правила до кожного виду, щоб уникнути вкладення.

Правила нагадують вам RelativeLayout, наприклад, встановлення ліворуч від деякого іншого виду.

app:layout_constraintBottom_toBottomOf="@+id/view1"

На відміну від RelativeLayout, ConstraintLayoutпропонується biasзначення, яке використовується для розміщення подання у розмірі 0% та 100% горизонтального та вертикального зміщення відносно ручок (позначених кругом). Ці відсотки (і фракції) пропонують плавне розташування подання за різною щільністю та розмірами екрана.

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

Базова ручка (довга труба із закругленими кутами, нижче ручки кола) використовується для вирівнювання вмісту виду з іншим еталоном виду.

Квадратні ручки (на кожному куті огляду) використовуються для зміни розміру зображення в точці на дюйм.

введіть тут опис зображення

Це повністю засноване на думці та моєму враженні ConstraintLayout


9
Ми все ще можемо створити вирівняний макет за допомогою RelativeLayout, тому я плутаюся, коли ConstraintLayout піклується про те, де RelativeLayout не може?

7
RelativeLayout - це двопрохідний макет, який страждає від подвійного оподаткування. Він повинен вимірювати / розміщувати не менше двох разів. ConstraintLayout не зазнає цього покарання за продуктивність.
Крістофер Перрі

5
@Ніщо так, ми все ще можемо створити вирівнювати макет за допомогою RelativeLayout. Але крім усіх згаданих тут, ConstraintLayout дозволяє використовувати негативні підрозділи поля та розміру у заздалегідь визначеному співвідношенні . Останній - це найнадійніший спосіб зберегти співвідношення 16: 9 для свого ImageView у CardView відповідно до Матеріального дизайну
Євген Брусов

4
Є кілька макетів, які неможливі в RelativeLayout, якщо ви не вкладете LinearLayout або інший RelativeLayout. Наприклад: центрування "стека" з 3 переглядів вертикально відносно іншого
виду

@ Gak2 Я не бачу нічого неможливого у вашому прикладі без вкладеного макета. Можливо, ти маєш на увазі щось інше зі «стеком», ніж я. Я просто використовую "layout_alignEnd", "layout_below", "layout _..." і можу створити з ним будь-який стек ...
Неймовірний січень

81

Відносні властивості відносного макета та обмеження

Відносні властивості відносного макета та обмеження

(1) Відносна схема:

android:layout_centerInParent="true"    

(1) Макет обмеження еквівалент:

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) Відносна схема:

android:layout_centerHorizontal="true"

(2) Еквівалент макета обмеження:

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

(3) Відносна схема:

android:layout_centerVertical="true"    

(3) Еквівалент макета обмеження:

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

(4) Відносна схема:

android:layout_alignParentLeft="true"   

(4) Макет обмеження еквівалент:

app:layout_constraintLeft_toLeftOf="parent"

(5) Відносна схема:

android:layout_alignParentStart="true"

(5) Еквівалент макета обмеження:

app:layout_constraintStart_toStartOf="parent"

(6) Відносна схема:

android:layout_alignParentRight="true"

(6) Макет обмеження еквівалент:

app:layout_constraintRight_toRightOf="parent"

(7) Відносна схема:

android:layout_alignParentEnd="true"    

(7) Макет обмеження еквівалент:

app:layout_constraintEnd_toEndOf="parent"

(8) Відносна схема:

android:layout_alignParentTop="true"

(8) Макет обмеження еквівалент:

app:layout_constraintTop_toTopOf="parent"

(9) Відносна схема:

android:layout_alignParentBottom="true" 

(9) Макет обмеження еквівалент:

app:layout_constraintBottom_toBottomOf="parent"

(10) Відносна схема:

android:layout_alignStart="@id/view"

(10) Еквівалент макета обмеження:

app:layout_constraintStart_toStartOf="@id/view"

(11) Відносна схема:

android:layout_alignLeft="@id/view" 

(11) Еквівалент макета обмеження:

app:layout_constraintLeft_toLeftOf="@id/view"

(12) Відносна схема:

android:layout_alignEnd="@id/view"  

(12) Еквівалент макета обмеження:

app:layout_constraintEnd_toEndOf="@id/view"

(13) Відносна схема:

android:layout_alignRight="@id/view"

(13) Еквівалент макета обмеження:

app:layout_constraintRight_toRightOf="@id/view"

(14) Відносна схема:

android:layout_alignTop="@id/view"  

(14) Макет обмеження еквівалент:

app:layout_constraintTop_toTopOf="@id/view"

(15) Відносна схема:

android:layout_alignBaseline="@id/view" 

(15) Макет обмеження еквівалент:

app:layout_constraintBaseline_toBaselineOf="@id/view"

(16) Відносна схема:

android:layout_alignBottom="@id/view"

(16) Еквівалент макета обмеження:

app:layout_constraintBottom_toBottomOf="@id/view"

(17) Відносна схема:

android:layout_toStartOf="@id/view"

(17) Макет обмеження еквівалент:

app:layout_constraintEnd_toStartOf="@id/view"

(18) Відносна схема:

android:layout_toLeftOf="@id/view"  

(18) Еквівалент макета обмеження:

app:layout_constraintRight_toLeftOf="@id/view"

(19) Відносна схема:

android:layout_toEndOf="@id/view"

(19) Еквівалент макета обмеження:

app:layout_constraintStart_toEndOf="@id/view"

(20) Відносна схема:

android:layout_toRightOf="@id/view"

(20) Еквівалент макета обмеження:

app:layout_constraintLeft_toRightOf="@id/view"

(21) Відносна схема:

android:layout_above="@id/view" 

(21) Еквівалент макета обмеження:

app:layout_constraintBottom_toTopOf="@id/view"

(22) Відносна схема:

android:layout_below="@id/view" 

(22) Еквівалент макета обмеження:

app:layout_constraintTop_toBottomOf="@id/view"


2
Чи можете ви розміщувати текст як зображення? Так що це буде дуже корисно мені і іншим у майбутньому.
Новий розробник

3
Усі, хто починає вивчати макети обмежень, повинні це бачити. Дякую.
грантеспо

1
Це корисна інформація, але це просто дамп документації і нічого не робить для пояснення різниці між ними.
інший випадковий користувач

1
Ні, я не встигаю шукати документи, це, безумовно, корисно. І написана простою мовою. Оголошення.
CodeToLife

46

Повідомив @davidpbr ConstraintLayout продуктивності

Я зробив два подібних макета на 7 дітей, по одному з батьками ConstraintLayoutта RelativeLayout. На основі інструменту відстеження методів Android Studio, схоже, ConstraintLayoutвитрачається більше часу на onMeasure та виконує додаткову роботу onFinishInflate.

Використовувана бібліотека ( support-v4, appcompat-v7…):

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

Версії пристроїв / Android відтворені на: Samsung Galaxy S6 (SM-G920A. Вибачте, немає атм Nexus). Android 5.0.2

Швидке порівняння методів відстеження:

1

Зразок Github repo: https://github.com/OnlyInAmerica/ConstraintLayoutPerf


з того ж випуску: я зараз закриваю це - альфа 4/5 принесла трохи покращення продуктивності. Ми, ймовірно, зможемо вдосконалити його більше, але це може зачекати пост 1.0.
Олександр

Чи можете ви пояснити, який інструмент ви використовували для створення цього чудового порівняння?
Nativ

2
@Nativ Monotirs-> CPU-> Піктограма відстеження часу
Андрій Т

18
Запуск та профільований той самий код на макеті обмежень: 1.0.1 на Nexus 5 з android 6.0.1, ось результати: Відносна компоновка - init 2ms на міру 30ms + 16ms = 62ms на Layouyt 7ms = 9ms всього 54 мс Макет обмеження - init 7ms Макет обмежень генерує параметри компонування + додавання перегляду ~ 7 * 2ms = 14ms В міру 60ms + 52ms ~ 112ms У макеті 8ms всього ~ 141ms Перша ініціалізація відносного макета майже втричі швидше, ніж обмеження.
Андрій Т

2
Макет обмежень вводиться так, щоб ієрархію вкладеного перегляду можна зменшити. Отже, менше ієрархії означає менше часу для переходу зверху вниз по дереву подання. Отже, в чому сенс створити вкладену ієрархію подання, яка може не знадобитися в макеті обмежень і порівняти її з відносною компоновкою, в якій у вас є більше шансів закінчитися вкладеною структурою?
кодектор

27

Нижче наведені відмінності / переваги:

  1. Макет обмежень має подвійну потужність як відносного макета, так і лінійного макета: Встановлюйте відносні положення поглядів (наприклад, відносна компоновка), а також встановлюйте ваги для динамічного інтерфейсу (що було можливо лише в лінійному макеті).

  2. Дуже потужне використання - групування елементів шляхом формування ланцюга. Таким чином ми можемо сформувати групу поглядів, яка в цілому може бути розміщена бажаним способом без додавання іншого шару ієрархії просто для формування іншої групи поглядів.

  3. Крім ваг, ми можемо застосувати горизонтальний і вертикальний зміщення, що є не що інше, як відсоток зміщення від центру. (зміщення 0,5 означає центральне вирівнювання. Будь-яке значення менше або більше означає відповідний рух у відповідному напрямку).

  4. Ще одна дуже важлива особливість полягає в тому, що вона поважає та надає функціональність для обробки зображень GONE, щоб макети не порушувались, якщо деякий вигляд встановлено на GONE через java-код. Більше можна знайти тут: https://developer.android.com/reference/android/support/constraint/ConstraintLayout.html#VisibilityBehavior

  5. Забезпечує потужність автоматичного обмеження застосування за допомогою інструмента «Синій друк» та «Візуальний редактор», що спрощує розробку сторінки.

Усі ці функції призводять до вирівнювання ієрархії перегляду, що покращує продуктивність, а також допомагає зробити чуйний та динамічний інтерфейс користувача, який може легше адаптуватися до різного розміру та щільності екрана.

Ось найкраще місце для швидкого навчання: https://codelabs.developers.google.com/codelabs/constraint-layout/#0


6) ConstraintLayout дає змогу розміщувати підгляди за заздалегідь визначеними співвідношеннями medium.com/google-developers/… . Це може бути корисно, наприклад, коли ви збираєтеся зберігати ImageView у 16: 9.
Євген Брусов

15

Велика різниця полягає в тому, що ConstraintLayout дотримується обмежень навіть у тому випадку, коли подання не було. Таким чином, він не порушить макет, якщо у вас є ланцюжок і ви хочете, щоб вид зник в середині.


ви можете мені навести який-небудь приклад? припустимо, там є три кнопки. Я приховую 2-ю кнопку, а 3-ю кнопку прикріплюю до 2-ї кнопки з ідентифікатором як btn2. Припустимо, я приховав 2-ю кнопку, то як третя кнопка могла знайти ідентифікатор 2-ї кнопки?

1
Це не правда. Якщо ви встановите видимість Кнопки як "НЕВИДИМО" замість "GONE", ви не будете порушувати обмеження. Як на мене, найбільша різниця, як сказав @Nikola, - це упередженість, яка допоможе вам створити більше "чуйних" поглядів.
zapotec

@Ніщо Припустимо, що кнопки знаходяться одна під одною. Навіть якщо ви приховуєте tButton 2, він все ще є у "контракті перегляду", або у вашому xml або коді. ConstraintLayout його буде дотримуватися, і кнопка 3 опиниться під кнопкою 1. У кнопці RelativeLayout кнопки 2 немає, контракт з нею відсутній, тож кнопка 3 буде в положенні за замовчуванням, тому ліворуч від екрана.
Herrbert74

@zapotec Я поважаю, що інші речі для вас важливіші, але для мене це справді класна різниця. Виправляє єдине, що я ненавидів у RelativeLayout. Використання невидимих ​​- це не варіант, оскільки це вимагатиме місця.
Herrbert74

7

Окрім @ dhaval-jivani відповіді.

Я оновив проект github проекту до останньої версії макета обмеження v.1.1.0-beta3

Я вимірював і порівнював час методу onCreate і час між початком onCreate і кінцем виконання останнього методу preformDraw, який видно в моніторі процесора. Всі тести були зроблені на Samsung S5 mini з android 6.0.1 Ось результати:

Новий старт (перше відкриття екрану після запуску програми)

Відносний макет

OnCreate: 123ms

Час останньої заготовкиВитягнути - Час OnCreate: 311,3ms

Макет обмеження

OnCreate: 120,3ms

Час останньої заготовкиВитягнути - Час OnCreate: 310ms

Крім того, я перевірив тест на працездатність з цієї статті , тут код і виявив, що цикл налічує менше 100 варіантів макета обмеження швидше під час виконання надуття, вимірювання та компонування, а потім варіантів із відносною компоновкою. А на старих Android-пристроях, як-от Samsung S3 з Android 4.3, різниця більша.

Як висновок я погоджуюся з коментарями до статті :

Чи варто переробляти старі погляди, щоб переключити його з RelativeLayout або LinearLayout?

Як завжди: Це залежить від 🙂

Я б нічого не рефактував, якщо у вас не виникнуть проблеми з продуктивністю в поточній ієрархії компонування або ви хочете внести значні зміни в макет. Хоча останнім часом я його не вимірював, в останніх випусках не знайшов проблем із продуктивністю. Тому я вважаю, що ви повинні безпечно ним користуватися. але - як я сказав - не мігруйте просто заради міграції. Робіть це лише в тому випадку, якщо в цьому є потреба та користь. Для нових макетів я майже завжди використовую ConstraintLayout. Це набагато краще порівняти з тим, що ми мали раніше.


6

Офіційно ConstraintLayoutце набагато швидше

У N випуску Android ConstraintLayoutклас забезпечує функціональність, аналогічну RelativeLayout, але за значно меншої вартості.


6

Справжнє запитання - чи є якась причина використовувати будь-який макет, крім макета обмеження? Я вважаю, що відповідь може бути «ні».

Тим, хто наполягає на тому, що вони спрямовані на початківців програмістів тощо, вони повинні надати певну причину, щоб вони поступалися будь-якій іншій схемі.

Макети обмежень краще в будь-якому випадку (вони коштують приблизно 150 кВт розміром APK.) Вони швидші, вони легші, вони більш гнучкі, вони краще реагують на зміни, вони вирішують проблеми, коли елементи відходять, вони краще відповідають кардинально різним типам екрану, і вони не використовують купу вкладених циклів так довго намальована структура дерева для всього. Ви можете помістити що завгодно, де завгодно, де завгодно.

Вони були трохи хитрими ще в середині 2016 року, коли редактор візуального макета просто був недостатньо хороший, але вони до того, що якщо у вас взагалі є макет, ви можете серйозно подумати про використання макета обмежень, навіть коли він робить те саме RelativeLayout, що і навіть просто LinearLayout. FrameLayoutsОчевидно, все ще мають своє призначення. Але я не бачу нічого будувати на цьому етапі. Якби вони почали з цього, вони б нічого іншого не додали.


1
Чи є докази це швидше?
Раджеш Насіт

1
Так. Це швидше. Макет розташований в одному розв'язувачі, а не ітерації через дерево. Для більшості речей це не має значення, оскільки це робиться при виклику до макета. Але, незважаючи на те, що дерево дерева переглядів створює купу переглядів усередині представлень, що вимагає дзвінків, що вимагають дзвінків Хоча теоретично це приємніше, але на практиці виконувати макет в одному біті коду набагато простіше, ніж переглядати все дерево перегляду. Він хотів би отримати більш вражаючим з великою кількістю переглядів , але ось тест з травня: medium.com/@krpiotrek/constraintlayout-performance-c1455c7984d7
Tatarize

У мене виникає ще одне питання, чи варто замінити всі існуючі відносні версії в додатку, над яким я працюю? Чи це значно покращить продуктивність?
Sreekanth Karumanaghat

@SreekanthKarumanaghat, схоже, ви ніколи не повернете час, необхідний для заміни тих, хто перейшов у час перемикання часу, врятував би вас. Ми говоримо про те, що 3,5 цикли знижуються до 3,25 мс у більшості випадків. Якщо це надає вам додаткову функцію або щось, що вам потрібно, то обов'язково, але суто на швидкості Хоча ми говоримо про натискання кнопки перетворення.
Tatarize

5

Висновок, який я можу зробити, є

1) Ми можемо робити дизайн інтерфейсу, не торкаючись частини XML коду, чесно кажучи, я вважаю, що Google скопіював, як призначений інтерфейс призначений для додатків iOS , це буде сенс, якщо ви знайомі з розвитком інтерфейсу в iOS, але відносно макета його важко встановити обмеження, не торкаючись дизайну xml .

2) По-друге, вона має ієрархію плоского виду на відміну від інших макетів, тому робить кращу ефективність, ніж відносна компоновка, яку ви могли бачити з інших відповідей

3) У нього також є додаткові речі, крім того, що має відносне розташування, наприклад, кругове відносне розміщення, де ми можемо розмістити інший погляд відносно цього в певному радіусі з певним кутом, який не можна робити у відносному макеті

Я кажу це ще раз: проектування інтерфейсу за допомогою макета обмежень - це те саме, що і проектування інтерфейсу в iOS, тому в майбутньому, якщо ви працюєте на iOS, вам буде легше, якщо ви використовували макет обмежень


1

Єдина відмінність, яку я зазначив, полягає в тому, що речі, встановлені у відносному макеті за допомогою перетягування, автоматично мають свої розміри відносно інших елементів, тому коли ви запускаєте додаток, ви отримуєте те, що ви отримуєте. Однак у макеті обмежень, навіть якщо ви перетягуєте елемент у вікні дизайну, під час запуску програми речі можуть зміщуватися навколо. Це можна легко виправити, встановивши обмеження вручну, або, більш ризиковано, рухатись правою кнопкою миші на елементі в дереві компонентів, вибираючи підменю макета обмеження, а потім натискаючи "Висновити обмеження". Сподіваюсь, це допомагає

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.