Различия между ConstraintLayout и RelativeLayout

219

Я смущен разницей между ConstraintLayoutи RelativeLayout. Может ли кто-нибудь сказать мне точные различия между ними?

b2mob
источник
9
ConstraintLayout в основном предназначен для новых программистов, чтобы они могли легко создавать макет с помощью визуального редактора, а не создавать макет вручную с помощью XML.
CopsOnRoad
1
@ Джек определенно имеет более глубокую цель для опытных разработчиков
Мозес Априко
@ 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 -->

Ручка базовой линии (длинная труба с закругленными углами, ниже ручки круга) используется для выравнивания содержимого вида с другой ссылкой на вид.

Квадратные маркеры (в каждом углу вида) используются для изменения размера вида в dps.

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

Это полностью основано на мнении и мое впечатление о ConstraintLayout

Никола Деспотоски
источник
9
Мы все еще можем создать сглаженный макет, используя RelativeLayout, поэтому я запутался, когда ConstraintLayout позаботился, а RelativeLayout не может?
7
RelativeLayout представляет собой двухпроходный макет, страдающий от двойного налогообложения. Он должен измерять / макет по крайней мере дважды. ConstraintLayout не переносит это снижение производительности.
Кристофер Перри
5
@ Ничего Да, мы все еще можем создать плоский макет, используя RelativeLayout. Но в дополнение ко всем упомянутым здесь, ConstraintLayout позволяет вам использовать отрицательные поля и размер подпредставлений в предопределенном соотношении . Последний - самый надежный способ сохранить соотношение 16: 9 для вашего ImageView в CardView в соответствии с дизайном материала
Евгений Брусов,
4
Есть некоторые макеты, которые невозможны в RelativeLayout, если вы не вложите LinearLayout или другой RelativeLayout. Например: центрирование «стека» из 3 видов по вертикали относительно другого вида
Gak2
@ 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"

Naimatullah
источник
2
Вы можете разместить как текст вместо изображения? Так что это будет очень полезно для меня, а также других в будущем.
Новый разработчик
3
Все, кто начинает изучать макеты ограничений, должны это видеть. Спасибо.
Грантспо
1
Это полезная информация, но это просто дамп документации и ничего не делает, чтобы объяснить разницу между ними.
Ещё
1
Нет, у меня нет времени просматривать документы, это, безусловно, полезно. И написано простым языком. Upvoting.
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 Atm). Android 5.0.2

Быстрое сравнение методов отслеживания:

1

Пример репозитория Github: https://github.com/OnlyInAmerica/ConstraintLayoutPerf

Давал Дживани
источник
из той же самой проблемы: я собираюсь закрыть это сейчас - альфа 4/5 принесла небольшое улучшение производительности. Вероятно, мы сможем улучшить его еще больше, но это может подождать пост 1.0.
Александр
Не могли бы вы объяснить, какой инструмент вы использовали для создания этого отличного сравнения?
Натив
2
@Nativ Monotirs-> CPU-> Значок трекера времени
Андрей T
18
Запустите и профилируйте тот же код с помощью компоновки ограничений: 1.0.1 на Nexus 5 с android 6.0.1, здесь результаты: Относительная компоновка - init 2ms по мере 30ms + 16ms = 62ms по Layouyt 7ms = 9ms всего 54 мс Ограничение Layout - init Макет ограничения 7 мс создает параметры макета + добавление вида ~ 7 * 2 мс = 14 мс При измерении 60 мс + 52 мс ~ 112 мс При макете всего 8 мс ~ 141 мс Первая инициализация относительного макета почти в три раза быстрее, чем ограничение.
Андрей Т
2
Макет ограничения введен так, чтобы иерархия вложенных представлений могла быть уменьшена. Таким образом, меньше иерархии означает меньше времени для перемещения сверху вниз в дереве представлений. Итак, какой смысл создавать вложенную иерархию представлений, которая может не понадобиться в макете ограничения и сравнивать ее с относительным макетом, в котором у вас больше шансов получить вложенную структуру?
Codepeaker
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 учитывает ограничения, даже если представление исчезло. Так что это не сломает макет, если у вас есть цепочка, и вы хотите, чтобы вид исчез в середине.

Herrbert74
источник
Можете привести пример? Предположим, есть 3 кнопки. Я скрою 2-ю кнопку, а 3-я кнопка прикреплена ко 2-й кнопке с идентификатором btn2. Предположим, что я скрываю 2-ю кнопку, тогда как 3-я кнопка может найти идентификатор 2-й кнопки?
1
Это не правда. Если вы установите видимость кнопки как «НЕВИДИМЫЙ» вместо «УТВЕРЖДЕННОЙ», вы не нарушите ограничения. Что касается меня, самым большим отличием, как сказал @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: 123мс

Время последней предварительной обработки - Время создания: 311,3 мс

Схема ограничения

OnCreate: 120,3 мс

Время последней предварительной формы - Время создания: 310 мс

Кроме того, я проверил тест производительности из этой статьи , здесь код и обнаружил, что во время подсчета циклов менее 100 вариант макета ограничения быстрее при выполнении надувания, измерения и компоновки, чем варианты с относительным макетом. А на старых устройствах Android, таких как Samsung S3 с Android 4.3, разница больше.

В заключение я согласен с комментариями к статье :

Стоит ли проводить рефакторинг старых представлений, включив его из RelativeLayout или LinearLayout?

Как всегда: это зависит 🙂

Я бы не стал проводить рефакторинг, если у вас нет проблем с производительностью в текущей иерархии макетов или вы все равно хотите внести существенные изменения в макет. Хотя я не измерял это в последнее время, я не обнаружил никаких проблем с производительностью в последних выпусках. Поэтому я думаю, что вы должны быть в безопасности, чтобы использовать его. но - как я уже сказал - не просто мигрировать ради миграции. Делайте это только в том случае, если в этом есть необходимость. Однако для новых макетов я почти всегда использую ConstraintLayout. Намного лучше сравнивать с тем, что было раньше.

Андрей Т
источник
6

Официально, ConstraintLayoutэто намного быстрее

В N-версии Android этот ConstraintLayoutкласс предоставляет аналогичную функциональность RelativeLayout, но по значительно более низкой цене.

Serv-вкл
источник
6

Реальный вопрос, который нужно задать, - есть ли причина использовать какой-либо макет, кроме макета ограничений? Я считаю, что ответ может быть нет.

Тем, кто настаивает на том, что они нацелены на начинающих программистов или тому подобное, они должны предоставить некоторую причину, по которой они уступают любому другому макету.

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

Они были немного сумасшедшими в середине 2016 года, когда визуальный редактор макетов просто не был достаточно хорош, но они настолько важны, что, если у вас вообще есть макет, вы можете серьезно подумать об использовании макета ограничений, даже когда он делает то же самое, что и RelativeLayout, или даже просто LinearLayout. FrameLayoutsясно, что у них есть цель. Но я не могу строить что-либо еще в этой точке. Если бы они начали с этого, они бы ничего не добавили.

Tatarize
источник
1
Есть ли доказательства, что это быстрее?
Раджеш Насит
1
Да. Это быстрее Макет находится в одном решателе, а не перебирает дерево. Для большинства вещей это не имеет значения, потому что это делается при вызове макета. Но дерево представлений, хотя и простое, создает множество представлений внутри представлений, которые требуют вызовов, требующих вызовов. Хотя теоретически это лучше, на практике выполнить макет в одном бите кода гораздо проще, чем перебирать все дерево представлений. Он хотел бы получить более впечатляющим с большим количеством просмотров , но вот тест с мая: medium.com/@krpiotrek/constraintlayout-performance-c1455c7984d7
Tatarize
Я сталкиваюсь с другим вопросом, должен ли я заменить все существующие Relativelayouts в приложении, над которым я работаю? Это значительно улучшит производительность?
Sreekanth Karumanaghat
@SreekanthKarumanaghat кажется, что вы никогда не вернете время, необходимое для их замены, во время переключения сэкономит вам. Мы говорим о циклах 3,5 мс, снижающихся до 3,25 мс в большинстве случаев. Если это дает вам дополнительную функцию или что-то, что вам нужно, то, конечно, но только по соображениям скорости, нет. Хотя мы говорим, нажимая кнопку преобразования.
Tatarize
5

Вывод, который я могу сделать,

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

2) Во-вторых, он имеет плоскую иерархию представлений, в отличие от других макетов, поэтому имеет лучшую производительность, чем относительный макет, который вы могли видеть из других ответов.

3) У него также есть дополнительные вещи, помимо относительного расположения, такие как круговое относительное расположение, где мы можем расположить другой вид относительно этого на определенном радиусе с определенным углом, который нельзя сделать в относительном расположении

Я повторю еще раз: разработка пользовательского интерфейса с использованием макета ограничений аналогична разработке пользовательского интерфейса в iOS, поэтому в будущем, если вы будете работать на iOS, вам будет проще, если вы использовали макет ограничений

Мурали Криш
источник
1

Единственное отличие, которое я заметил, заключается в том, что для объектов, заданных в относительном макете с помощью перетаскивания, автоматически выводятся их размеры относительно других элементов, поэтому при запуске приложения вы видите то, что получаете. Однако в макете ограничений, даже если вы перетаскиваете элемент в режиме конструктора, при запуске приложения все может быть смещено. Это можно легко исправить, установив ограничения вручную или, что более рискованно, состоит в том, чтобы щелкнуть правой кнопкой мыши элемент в дереве компонентов, выбрать подменю макета ограничений, а затем щелкнуть «Вывести ограничения». Надеюсь это поможет

Wilson
источник