Я смущен разницей между ConstraintLayout
и RelativeLayout
. Может ли кто-нибудь сказать мне точные различия между ними?
RealtiveLayout
, LinearLayout
, и GridLayout
т.д.) , чтобы получить иерархию вид , что они хотят.
Я смущен разницей между ConstraintLayout
и RelativeLayout
. Может ли кто-нибудь сказать мне точные различия между ними?
RealtiveLayout
, LinearLayout
, и GridLayout
т.д.) , чтобы получить иерархию вид , что они хотят.
Ответы:
Намерение 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
Эквивалентные свойства относительного макета и макета ограничения
(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"
Сообщил @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
Быстрое сравнение методов отслеживания:
Пример репозитория Github: https://github.com/OnlyInAmerica/ConstraintLayoutPerf
Ниже приведены различия / преимущества:
Макет ограничения имеет двойную мощность как относительного макета, так и линейного макета: установите относительные позиции видов (например, относительный макет), а также установите вес для динамического интерфейса пользователя (что было возможно только в линейном макете).
Очень мощное применение - группировка элементов путем формирования цепочки. Таким образом, мы можем сформировать группу представлений, которые в целом могут быть размещены желаемым образом без добавления другого уровня иерархии просто для формирования другой группы представлений.
В дополнение к весам мы можем применить горизонтальное и вертикальное смещение, которое является ничем иным, как процентом смещения от центра. (Смещение 0,5 означает выравнивание по центру. Любое значение меньше или больше означает соответствующее движение в соответствующем направлении).
Еще одна очень важная особенность заключается в том, что он уважает и предоставляет функциональные возможности для обработки представлений GONE, чтобы макеты не ломались, если для некоторых представлений установлено значение GONE через код Java. Больше можно найти здесь: https://developer.android.com/reference/android/support/constraint/ConstraintLayout.html#VisibilityBehavior
Обеспечивает мощь автоматического применения ограничений с помощью синей печати и визуального редактора, который упрощает дизайн страницы.
Все эти функции приводят к выравниванию иерархии представлений, что повышает производительность, а также помогает создавать отзывчивый и динамический интерфейс, который может легче адаптироваться к разным размерам экрана и плотности.
Вот лучшее место для быстрого изучения: https://codelabs.developers.google.com/codelabs/constraint-layout/#0
Большая разница в том, что ConstraintLayout учитывает ограничения, даже если представление исчезло. Так что это не сломает макет, если у вас есть цепочка, и вы хотите, чтобы вид исчез в середине.
В дополнение к @ 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. Намного лучше сравнивать с тем, что было раньше.
Официально, ConstraintLayout
это намного быстрее
В N-версии Android этот
ConstraintLayout
класс предоставляет аналогичную функциональностьRelativeLayout
, но по значительно более низкой цене.
Реальный вопрос, который нужно задать, - есть ли причина использовать какой-либо макет, кроме макета ограничений? Я считаю, что ответ может быть нет.
Тем, кто настаивает на том, что они нацелены на начинающих программистов или тому подобное, они должны предоставить некоторую причину, по которой они уступают любому другому макету.
Макеты ограничений лучше во всех отношениях (они стоят около 150 КБ в размере APK). Они быстрее, они проще, они более гибкие, они лучше реагируют на изменения, они решают проблемы, когда элементы уходят, они лучше соответствуют радикально различным типам экранов и не используют кучу вложенных циклов с такой длинной Вытянутая древовидная структура для всего. Вы можете поместить что угодно где угодно, относительно чего угодно, где угодно.
Они были немного сумасшедшими в середине 2016 года, когда визуальный редактор макетов просто не был достаточно хорош, но они настолько важны, что, если у вас вообще есть макет, вы можете серьезно подумать об использовании макета ограничений, даже когда он делает то же самое, что и RelativeLayout
, или даже просто LinearLayout
. FrameLayouts
ясно, что у них есть цель. Но я не могу строить что-либо еще в этой точке. Если бы они начали с этого, они бы ничего не добавили.
Вывод, который я могу сделать,
1) Мы можем сделать дизайн пользовательского интерфейса, не касаясь XML-части кода, если честно, я чувствую, что Google скопировал дизайн пользовательского интерфейса в приложениях для iOS , это будет иметь смысл, если вы знакомы с разработкой пользовательского интерфейса в iOS, но в относительной компоновке это трудно установить ограничения, не касаясь дизайна XML .
2) Во-вторых, он имеет плоскую иерархию представлений, в отличие от других макетов, поэтому имеет лучшую производительность, чем относительный макет, который вы могли видеть из других ответов.
3) У него также есть дополнительные вещи, помимо относительного расположения, такие как круговое относительное расположение, где мы можем расположить другой вид относительно этого на определенном радиусе с определенным углом, который нельзя сделать в относительном расположении
Я повторю еще раз: разработка пользовательского интерфейса с использованием макета ограничений аналогична разработке пользовательского интерфейса в iOS, поэтому в будущем, если вы будете работать на iOS, вам будет проще, если вы использовали макет ограничений
Единственное отличие, которое я заметил, заключается в том, что для объектов, заданных в относительном макете с помощью перетаскивания, автоматически выводятся их размеры относительно других элементов, поэтому при запуске приложения вы видите то, что получаете. Однако в макете ограничений, даже если вы перетаскиваете элемент в режиме конструктора, при запуске приложения все может быть смещено. Это можно легко исправить, установив ограничения вручную или, что более рискованно, состоит в том, чтобы щелкнуть правой кнопкой мыши элемент в дереве компонентов, выбрать подменю макета ограничений, а затем щелкнуть «Вывести ограничения». Надеюсь это поможет