- Можно ли поместить ConstraintLayout внутри ScrollView?
- 8 ответов
- 7 minute guide on implementing ConstraintLayout in Android
- anitaa1990/ConstraintLayout-Sample
- ConstraintLayout-Sample — A demo app to showcase constraint layout implementation in Android
- Step 1: Add ConstraintLayout to project
- Step 2: Add a NestedScrollView as the root of the layout
- Step 3: Add a ConstraintLayout as the only child of the NestedScrollView
- Step 4: Add Module No 1 (Image Banner) to the layout:
- Step 5: Add Module No 2 (List of trailers) to the layout:
- Step 6: Add Module No 3 (CardView) to the layout:
- Step 7: Add Module No 4 (Crew and Cast Details) to the layout:
- Step 8: Add Module No 5 (Similar Movies layout) to the layout:
- Работа с ConstraintLayout через XML-разметку
- Навигация:
- Добавляем в проект
- Constraints. Привязываем элементы друг к другу
- Задаем размеры View
- Задаем размеры View на основе соотношения сторон
- Выставляем относительное расположение View внутри ConstraintLayout
- Особенности привязки линий
- Особенности привязки по Baseline
- Создаем цепи (chains)
- Стиль spread
- Стиль spread_inside
- Стиль packed
- Стиль weighted
- Указываем отступы с учетом скрытых элементов
- Разбираемся с Guidelines
- Настраиваем параметры ConstraintLayout из кода
- Коротко об анимации
- Стоит ли пользоваться ConstraintLayout?
Можно ли поместить ConstraintLayout внутри ScrollView?
так недавно, с Android Studio 2.2 есть новый ConstraintLayout, который делает проектирование намного проще, но в отличие от RelativeLayout и Linearlayout , Я не могу использовать ScrollView окружить ConstraintLayot . Возможно ли это? Если да, то как?
8 ответов
произошла ошибка с ConstraintLayout внутри ScrollViews, и она была исправлена. google исправил ошибку в Android Studio 2.2 Preview 2 (constraintlayout 1.0.0-alpha2).
проверьте эту ссылку для нового обновления (предварительный просмотр 2): работает правильно внутри ScrollView и RecycleView
попробуйте добавить android:fillViewport=»true» в ScrollView.
использовать NestedScrollView С viewport true работает хорошо для меня
Set ScrollView layout_height как wrap_content тогда он будет работать нормально. Ниже приведен пример, который может помочь кому-то. Я использовал compile ‘com.android.support.constraint:constraint-layout:1.0.2’ для сервировки ограничения.
Я сообщил об ошибке команде Google.
вы можете посмотреть это здесь.
Я потратил 2 дня, пытаясь преобразовать макеты в ConstraintLayout в так называемом «стабильном» выпуске Android Studio 2.2 и у меня нет ScrollView для работы в конструкторе. Я не собираюсь начинать маршрут добавления ограничений в XML для Views это дальше по прокрутке. Ведь это должен быть инструмент визуального проектирования.
и количество ошибок рендеринга, переполнений стека и тематических вопросов, которые у меня были, привело меня к выводу, что все ConstraintLayout реализация все еще пронизана ошибками. Если вы не разрабатываете простые макеты, я бы оставил его в покое, пока у него не будет еще несколько итераций.
это 2 дня, которые я не собираюсь возвращаться.
С момента фактического ScrollView инкапсулируется в CoordinatorLayout С Toolbar .
. Я должен был определить android:layout_marginTop=»?attr/actionBarSize» чтобы сделать прокрутку рабочей:
выше также работает с NestedScrollView вместо ScrollView . Определение android:fillViewport=»true» мне не нужно.
новая Android studio после 2.2 ConstraintLayout теперь работает правильно внутри ScrollView.
Источник
7 minute guide on implementing ConstraintLayout in Android
Jul 22, 2018 · 7 min read
ConstraintLayout has been available for a while now in Android. While there were a lot of advantages to using it (namely, reduce the number of nested views, which will improve the performance of our layout files), I always had a lot of difficulty in learning to implement them in a project. So I decided to take the time to fully understand the inner workings of ConstraintLayout so it might be useful to work with in the future.
I took a single screen f rom a project of mine and decided to implement it using ConstraintLayout. At the end of the article, we should have implemented something like this:
For those of you who would like to skip the article and go directly to the code, you can find it in Github:
anitaa1990/ConstraintLayout-Sample
ConstraintLayout-Sample — A demo app to showcase constraint layout implementation in Android
Note: I am using the latest version of Android Studio (3.3) which includes the new AndroidX support library (28). If you are using previous versions of the support library, please change the following packages:
The first thing we are going to do is to split the above layout into 5 different modules:
- Image Banner
- List of Trailers to display horizontally
- CardView with the Movie details
- Read More button — Cast and Crew layout
- Similar Movies layout
Now let’s start coding!
Step 1: Add ConstraintLayout to project
We will need to add the dependancy for the ConstraintLayout from the support library
Step 2: Add a NestedScrollView as the root of the layout
So if you look at the image above, you will notice that the first thing to do would be ensure that the entire view is scrollable. So we would need to add a NestedScrollView .
Step 3: Add a ConstraintLayout as the only child of the NestedScrollView
Step 4: Add Module No 1 (Image Banner) to the layout:
If you look at the image above, there is an image banner at the top of the view. The width of the image is equal to the image size. The height of the image is approximately around
25% of the screen size. Now how do we define that using ConstraintLayout?
Using Constraints, of course. In the above layout, notice that we have added the following constraints to the ImageView. I will define what each one means:
- app:layout_constraintEnd_toEndOf=”parent” — This means that the end of the widget will be aligned to the end of the parent view. i.e. the right of the ImageView will be aligned to the right of the parent view.
- app:layout_constraintStart_toStartOf=”parent” — This means that the start of the widget will be aligned to the start of the parent view. i.e. the left of the ImageView will be aligned to the left of the parent view.
- app:layout_constraintTop_toTopOf=”parent” — This means that the top of the widget will be aligned to the top of the parent view. i.e. the top of the ImageView will be aligned to the top of the parent view.
- app:layout_constraintDimensionRatio=”H,16:8″ — ConstraintLayout allows us to define ratios to any widget. It has two components: orientation ( which can be ‘ W ’ or ‘ H ’ ) , and the ratio .
In the above example, since we have set the orientation as ‘ H ’, the height of the ImageView will follow a 16:8 ratio (2:1 ratio), while the width of the ImageView will match the constraints to parent .i.e. the left, right and top of the imageView will be attached to the left, right and top of the parent view. essentially stretching the widget to fill the entire width of the parent.
Consequently, whatever size screen or orientation the layout appears on, the ImageView will always be the same width as the parent and the height half of that height.
Step 5: Add Module No 2 (List of trailers) to the layout:
The recyclerView would be defined with left, right and top constraints equal to the parent. We have defined a margin of around 145dp to the top of the recyclerView. We could define this using Guideline (but evidently Guideline works only when a fixed height layout can be defined so going with marginTop.
Step 6: Add Module No 3 (CardView) to the layout:
The CardView defined, includes the movie title, movie genre, movie description, movie status, movie runtime and a read more button.
If you notice, the CardView includes two additional constraints:
- app:layout_constrainedHeight=”true” —This will wrap the CardView height according to its contents.
- app:layout_constrainedWidth=”true” —This will wrap the CardView width according to its contents.
- app:layout_constraintTop_toBottomOf=”@+id/list_videos” —This will ensure that the CardView will be aligned to the bottom of the RecyclerView (trailers list).
Step 7: Add Module No 4 (Crew and Cast Details) to the layout:
We first include a layout inside the CardView below the Read More button.
Now we need to create a new layout file called list_cast.xml and define the layout for displaying the cast and crew details.
Now we create a new layout file called item_cast_crew.xml to define the list item view for the cast and crew details:
Step 8: Add Module No 5 (Similar Movies layout) to the layout:
We include another layout inside the parent ConstraintLayout below the CardView.
Now we need to create a new layout file called list_similar_movies.xml and define the layout for displaying the similar movies list.
Now we create a new layout file called item_similar_movies.xml to define the list item view for each movie item.
And viola, that’s it!
Note: I did not want to go into details defining the Adapter classes and the activity classes because the focus of this article is to understand the implementation of ConstraintLayout. If you would like to check out the full source code of the app, please click here.
Before finishing the article, I wanted to highlight some of the constraints I have used in this article, in order to better understand the concept of ConstraintLayout .
- app:layout_constraintEnd_toEndOf — This means that the end of the widget will be aligned to the end of the parent view.
- app:layout_constraintStart_toStartOf — This means that the start of the widget will be aligned to the start of the parent view.
- app:layout_constraintTop_toTopOf — This means that the top of the widget will be aligned to the top of the parent view.
- app:layout_constraintTop_toBottomOf — This means that the top of the widget will be aligned to the bottom of the parent view.
- app:layout_constraintBottom_toTopOf — This means that the bottom of the widget will be aligned to the top of the parent view.
- app:layout_constraintBottom_toBottomOf — This means that the bottom of the widget will be aligned to the bottom of the parent view.
- app:layout_constraintLeft_toTopOf — This means that the left of the widget will be aligned to the top of the parent view.
- app:layout_constraintLeft_toBottomOf— This means that the left of the widget will be aligned to the bottom of the parent view.
- app:layout_constraintLeft_toLeftOf— This means that the left of the widget will be aligned to the left of the parent view.
- app:layout_constraintLeft_toRightOf — This means that the left of the widget will be aligned to the right of the parent view.
- app:layout_constraintRight_toTopOf— This means that the right of the widget will be aligned to the top of the parent view.
- app:layout_constraintRight_toBottomOf — This means that the right of the widget will be aligned to the bottom of the parent view.
- app:layout_constraintRight_toLeftOf— This means that the right of the widget will be aligned to the left of the parent view.
- app:layout_constraintRight_toRightOf — This means that the right of the widget will be aligned to the right of the parent view.
- app:layout_constraintDimensionRatio=”H,16:8″ — ConstraintLayout allows us to define ratios to any widget. It has two components: orientation ( which can be ‘ W ’ or ‘ H ’ ) , and the ratio .
If we set the orientation as ‘ H ’, and the ratio as 16:8, then the height of the ImageView will follow a 16:8 ratio (2:1 ratio), while the width of the ImageView will match the constraints to parent. So, whatever size screen or orientation the layout appears on, the ImageView will always be the same width as the parent and the height half of that height. - app:layout_constraintHorizontal_bias — This means that the position of a view along the horizontal axis can be defined using a bias value. For instance, a bias value of 0.5, will align the widget in the center horizontally .
- app:layout_constraintVertical_bias — This means that the position of a view along the vertical axis can be defined using a bias value. For instance, a bias value of 0.5, will align the widget in the center vertically .
- app:layout_constrainedHeight=”true” —This will wrap the CardView height according to its contents.
- app:layout_constrainedWidth=”true” —This will wrap the CardView width according to its contents.
Seems like a lot. But it is quite easy to implement once we get the hang of it. You can checkout some of the other constraints we have not looked at in this article.
Thanks for reading guys! I hope you enjoyed this article and found it useful, if so please hit the Clap button. Let me know your thoughts in the comments section.
Источник
Работа с ConstraintLayout через XML-разметку
Привет! Меня зовут Гавриил, я Android-лид Touch Instinct.
В марте Google выкатил релизное обновление ConstraintLayout. Презентовали его еще на прошлом Google I/O. С того момента прошел почти год, ConstraintLayout стал лучше, быстрее и оброс новыми возможностями. Например, приятно, что появилась возможность объединения элементов в цепи — это позволяет использовать ConstraintLayout вместо LinearLayout.
О всех новых и старых возможностях ConstraintLayout я и постараюсь рассказать в этой статье. Предупрежу сразу — статья будет длинная и других семи частей не будет. Про визуальный редактор ConstraintLayout в статье не будет ни слова — только XML-разметка (по старинке) и немного кода.
Навигация:
Добавляем в проект
Теперь можно использовать ConstraintLayout у себя в проекте:
Constraints. Привязываем элементы друг к другу
Constraints — это линии, на основе которых располагается view внутри ConstraintLayout. Constraints могут быть привязаны к сторонам самого ConstraintLayout или к сторонам других view внутри ConstraintLayout. Constraints можно разделить на вертикальные и горизонтальные.
- правой стороны (Right), левой стороны (Left);
- начальной стороны (Start), конечной стороны (End).
- верхней стороны (Top), нижней стороны (Bottom);
- базовой линии (Baseline).
Вертикальное и горизонтальное constraints друг с другом не связаны.
Напомню, что Baseline — это линия выравнивания контента элемента. Пример — для TextView это линия строки, на которой пишется текст. Если у view выставлен Baseline сonstraint, то базовая линия элемента будет находиться на уровне базовой линии view, к которой привязан сonstraint.
Для начала, проще всего рассматривать сonstraints, как стороны view. То есть можно, например, привязать левую сторону view B к правой стороне view A — тогда view B будет располагаться справа от view A .
Общий формат атрибутов для привязки сonstraint выглядит следующим образом:
- X — сonstraint привязываемой view;
- Y — сторона view, к которой привязываются;
- Z — id view, к которой привязываются, или parent , если привязать нужно к стороне ContraintLayout.
Основные правила привязки сторон:
- привязывать между собой можно только Start и End , Left и Right , Top и Bottom . То есть, нельзя, например, привязать Left к Start или Baseline к Top;
- Baseline можно привязать только к Baseline другой view;
- при привязке Start/End игнорируются привязки Left/Right;
- при привязке Baseline игнорируются привязки Top/Bottom;
- не привязывайте view с внешней стороны ConstraintLayout, например, layout_constraintRight_toLeftOf=»parent» . ConstraintLayout обработает такую привязку, но как себя при этом поведет, сложно предсказать.
Задаем размеры View
Чтобы задать размеры view, используются обязательные атрибуты layout_width и layout_height , и необязательные атрибуты layout_constraintWidth_default и layout_constraintHeight_default .
Значение атрибутов layout_constraintWidth_default и layout_constraintHeight_default по умолчанию равно spread .
Размер view могут быть указан, как (на примере высоты):
- layout_height=»100dp» — обозначим, как fixed_size. View будет указанного размера;
- layout_height=»wrap_content» — обозначим, как any_size. Размер вычисляется самой view, может быть любым;
- layout_height=»0dp» + layout_constraintHeight_default=»spread» — обозначим, как match_constraint_spread. Размер view будет равен расстоянию между constraints. Для высоты, например, это расстояние между верхним constraint и нижним constraint;
- layout_height=»0dp» + layout_constraintHeight_default=»wrap» — обозначим, как match_constraint_wrap. Размер вычисляется самой view, но не может выйти за рамки constraints.
Важно! Указывать размер match_parent или fill_parent запрещено. Чтобы размер view совпадал с размерами ConstraintLayout, достаточно просто привязать constraints к сторонам ConstraintLayot и использовать размер match_constraint_spread.
Если указан размер match_constraint_wrap или match_constraint_spread, стоит учесть, что:
- чтобы такой тип размера работал корректно, у view должны быть привязаны два constraint: для ширины это Left и Right или Start и End . Для высоты — Top и Bottom ;
- размер view не может выйти за рамки constraints;
- можно выставить минимальный и максимальный размер view в рамках constraints. Для этого используются атрибуты layout_constraintWidth_min , layout_constraintHeight_min , layout_constraintWidth_max , layout_constraintHeight_max ;
- не стоит выставлять такой тип размера для высоты, если у view привязан Baseline constraint — вероятно, высота элемента будет рассчитываться неверно.
Для других типов размеров стоит учитывать, что:
- если указан any_size или fixed_size, то элемент может выходить за рамки constraints. Например, в примере из раздела «Constraints», если в текстовых view задать длинный текст, то он будет выходить за рамки ConstraintLayout;
- на размеры ConstraintLayout влияют view с fixed_size, any_size и match_constraint_wrap. Если покажется, что размер ConstraintLayout рассчитан неверно, скорее всего, виновата одна из view с такими размерами;
Задаем размеры View на основе соотношения сторон
ConstraintLayout позволяет рассчитывать высоту или ширину view на основе заданного соотношения сторон. То есть, например, при соотношении сторон 16:9 , если высота будет 900dp , то ширина рассчитается, как 1600dp .
За это отвечает атрибут layout_constraintDimensionRatio . Задать соотношение сторон можно в двух форматах: текстовом 16:9 или числовом 1.8 . При этом перед значением можно указать символ стороны, которая находится в числителе соотношения. Например, H,16:9 будет означать, что 16 — это значение, соотвествующее высоте (H), а 9 — ширине (W).
Значение в layout_constraintDimensionRatio учитывается при расчете размеров view, только если хотя бы одна из сторон выставлена в match_constraint_wrap или match_constraint_spread.
Выставляем относительное расположение View внутри ConstraintLayout
Если у view привязать два горизонтальных constraints, то ей можно выставить горизонтальное относительное расположение. То же применимо и для вертикальных constraints.
За горизонтальное расположение отвечает атрибут layout_constraintHorizontal_bias , за вертикальное — layout_constraintVertical_bias . Указывается относительное расположение значением от 0 до 1.
По сути, это более гибкая замена атрибута layout_gravity . Например, для горизонтального расположения 0 будет означать расположение крайне слева, 0.5 — по центру, 1 — крайне справа. По умолчанию — 0.5.
Теперь, например, выставим значение 0.3. Это будет означать, что 30% не заполненного view места будет слева от view, а 70% — справа. Если же размер view больше размера расстояния между constraints, то 30% выходящего за constraints размера будет слева от ограничений, а 70% — справа.
Небольшое важное замечание: если в манифесте выставлена поддержка RTL языков, то layout_constraintHorizontal_bias вместо «слева» будет располагать элементы «от начала», а вместо «справа» — «от конца». То есть тем, кто поддерживает RTL языки стоит учитывать, что явно выставить расположение «слева» и «справа» не выйдет. По крайней мере, я такой возможности не нашел.
Особенности привязки линий
После презентации ConstraintLayout его часто сравнивали с RelativeLayout. Но, на самом деле, у них принципиально разные расчеты расположения элементов. В RelativeLayout у view просто указывается, с какой стороны другой view ей нужно находиться — «слева от», «справа от» и т.д. В ConstraintLayout constraints привязываются к сторонам других views и расположение view зависит от того, как ее constraints будут рассчитаны.
Для расположения constraint сперва рассчитывается расположение view, к которой этот constraint привязан. А для расположения view сперва рассчитываются все указанные для нее constraints. Циклические зависимости view и constraints при этом запрещены, так что, фактически, внутри ConstraintLayout строится направленный ациклический граф зависимостей constraints от view и view от constraints. Все расчеты производятся последовательно, начиная от не зависимых элементов графа.
Для простоты советую разделять вертикальные и горизонтальные зависимости на две независимые группы, как-будто внутри ConstraintLayout строится отдельно граф вертикальных зависимостей и отдельно — горизонтальных.
Но, вообще говоря, стоит понимать, что вертикальные параметры view, косвенно, могут зависеть от горизонтальных параметров другой view. Пример — расчет размера на основе соотношения сторон: при изменении ширины view меняется и ее высота. То есть, если у view изменится ширина из-за изменений ее горизонтальных constraints, то высота view тоже изменится.
Теперь рассмотрим любопытный пример расчета вертикальных constraints:
Результат:
View A просто привязан к левой и верхней сторонам ConstraintLayout, то есть находится слева сверху.
View B привязан странным образом — Top(B)->bottom(A) и Bottom(B)->top(A) , — расстояние между его вертикальными constraints, фактически, отрицательное. Сама высота B выставлена в match_constraint_spread.
View C находится справа от A — Left(C)toRight(A) — и (вроде как) снизу от B — Top(C)toBottom(B) .
По горизонтальному расположению вопросов возникнуть не должно. Теперь объясню вертикальное расположение.
Последовательность вертикальных расчетов:
- Для расчета C необходимо рассчитать ее нижний constraint;
- Для расчета нижнего constraint C необходимо рассчитать верхнюю сторону B ;
- Для расчета верхней стороны B необходимо рассчитать ее нижний и верхний constraints;
- Для расчета нижнего и верхнего constraints B необходимо рассчитать верхнюю и нижнюю стороны A ;
- A просто располагается слева-сверху, размеры рассчитывает сам.
Результаты вертикальных расчетов:
- Верхняя сторона A находится на уровне верхней стороны ConstraintLayout, нижняя рассчитывается по размеру текста A , так как у A высота wrap_content;
- Верхний constraint B на уровне нижней стороны A , нижний привязан к верхней стороне A , то есть он на уровне верхней стороны ConstraintLayout;
- Так как высота B — match_constraint_spread, то верхняя сторона B — на уровне нижней стороны A , а нижняя — на уровне верхней стороны ConstraintLayout. Это странно, но, фактически, высота B — отрицательная.
- Верхний constraint C привязан к нижней стороне B , то есть он на уровне верхней стороны ConstraintLayout;
- В итоге, верхняя сторона C на уровне верхней стороны ConstraintLayout, нижняя рассчитывается по размеру текста C , так как у A высота wrap_content.
В общем, на мой взгляд, такой алгоритм расчета стоит учитывать, чтобы понимать, где будет располагаться view в конечном счете.
Особенности привязки по Baseline
View, привязанная по Baseline, не может быть ограничена сверху и снизу, то есть Top и Bottom constraints будут игнорироваться. Это значит, что для такой view нельзя выставить размер match_constraint_spread или match_constraint_wrap.
Из этого не совсем очевидно следует, что по Baseline стоит привязывать невысокие view к высоким. Иначе есть шанс, что высокая view выйдет за рамки ConstraintLayout или размер ConstraintLayout будет рассчитан неверно.
Пример некорректной Baseline-привязки:
Результат:
Высота ConstraintLayout (в черной рамке) равна высоте большой TextView (в красной рамке), так как высота TextView выставлена, как wrap_content .
Базовая линия большой TextView привязана к базовой линии малой TextView (в зеленой рамке), так что текст находится на одной линии.
При этом большая TextView выходит за рамки ConstraintLayout.
Создаем цепи (chains)
При привязке сторон есть одно интересное правило — если привязать две стороны двух элементов друг к другу Left(B)toRight(A) и Right(A)toLeft(B) , то элементы будут выделены в цепь и к ним будут применяться особые правила расположения.
Цепью считается набор элементов, стороны которых привязаны друг к другу. Цепи определяются автоматически на основе привязок элементов внутри ConstraintLayout . Цепь располагается на основе привязок ее крайних элементов, а элементы внутри цепи располагаются по правилам определенного стиля цепи. Стиль цепи задается атрибутом layout_constraint
Пример цепи: правило Right(A)toLeft(B) + Left(B)toRight(A) свяжет элементы A и B в цепь, а Left(A)toLeft(parent) + Right(B)toRight(parent) привяжет всю цепь элементов к внешним сторонам ConstraintLayout .
Стиль цепи и его параметры берутся из атрибутов головного элемента цепи — самого левого, начального или самого верхнего.
Стиль spread
Элементы цепи распределяются равномерно, то есть отступы между элементами и от элементов до границ цепи будут одинаковые. Используется по умолчанию;
Стиль spread_inside
Элементы цепи распределяются так же, как и при стиле spread , но отступы от границ цепи всегда равны нулю;
Стиль packed
Элементы располагаются группой друг за другом. Такой стиль позволяет устанавливать относительную позицию группы элементов в доступном цепи пространстве через атрибут layout_constraint<*>_bias . Bias атрибут нужно указывать у головного элемента цепи;
Стиль weighted
Элементы располагаются в соответствии с их весом по аналогии с тем, как работает LinearLayout. Чтобы такой стиль заработал, одна из view цепи должна иметь размер match_constraint_spread. Для указания веса элемента используются атрибуты layout_constraintHorizontal_weight и layout_constraintVertical_weight .
Указываем отступы с учетом скрытых элементов
Отступы указываются стандартными атрибутами layout_margin
Отдельные правила были введены для скрытых элементов, то есть элементов, у которых Visibility выставлено в значение GONE . Когда элемент скрыт, обычные отступы от его сторон игнорируются, но используются специальные gone-отступы . Его размеры при этом при расчетах считаются равными нулю. Gone-отступы представлены атрибутами: layout_goneMargin
Другими словами, допустим, у элемента A выставлен отступ слева от элемента B равный 10dp , а gone-отступ слева выставлен 50dp . Если элемент B скрыт ( GONE ), то отступ элемента A слева будет 50dp , если элемент B — VISIBLE или INVISIBLE , то отступ элемента A слева будет 10dp .
Разбираемся с Guidelines
Guideline — это аналог линии, устанавливаемой на макетах в визуальных редакторах, по которой дизайнеры выравнивают элементы. Такую линию представляет view класса android.support.constraint.Guideline . Guideline может быть горизонтальным или вертикальным — это указывается атрибутом android:orientation . Сам guideline нулевого размера, не занимает места в контейнере и всегда привязан только к сторонам ConstraintLayout.
Guideline используется, чтобы привязывать к нему стороны view выравнивая их тем самым по одной линии.
Расположение guideline контролируется тремя атрибутами:
- layout_constraintGuide_begin — отступ от левой ( Left , а не Start ) стороны ConstraintLayout для вертикальных gudeline и от верхней стороны — для горизонтальных;
- layout_constraintGuide_end — отступ от правой ( Right , а не End ) стороны ConstraintLayout для вертикальных guideline и от нижней стороны — для горизонтальных;
- layout_constraintGuide_percent — относительный отступ guideline в процентах от левой стороны ConstraintLayout для вертикальных gudeline и от верхней стороны — для горизонтальных. Указывается числом от 0 до 1.
Настраиваем параметры ConstraintLayout из кода
За это отвечает отдельный класс — android.support.constraint.ConstraintSet .
Создать этот ConstraintSet можно тремя способами:
- скопировать параметры из существующего ConstraintLayout ;
- скопировать параметры из *.xml файла, на основе которого создается ConstraintLayout ;
- скопировать другой ConstraintSet .
Описание методов для изменения ConstraintSet можно посмотреть в документации (их очень много).
Чтобы применить ConstraintSet к ConstraintLayout используйте метод applyTo .
Естественно, также можно напрямую изменять LayoutParams конкретного элемента и затем явно вызывать requestLayout . Класс, представляющий все параметры расположения элемента в ConstraintLayout — это android.support.constraint.ConstraintLayout.LayoutParams .
Коротко об анимации
Для анимаций в ConstraintLayout не предусмотрено специальных методов. ConstraintLayout наследуется от ViewGroup , так что для анимации расположения элементов используются те же инструменты, что и для обычных контейнеров: ValueAnimator , TransitionManager и так далее.
Стоит ли пользоваться ConstraintLayout?
- обладает широким спектром возможностей, что позволяет реализовывать сложные взаиморасположения элементов на экране;
- в Android Studio для этого контейнера имеется удобный визуальный редактор;
- в большинстве случаев можно избежать излишней вложенности контейнеров друг в друга, что положительно влияет на производительность и читаемость кода;
- заменяет стандартные контейнеры, то есть достаточно выучить один раз ConstraintLayout и не пользоваться в дальнейшем такими контейнерами, как: FrameLayout , LinearLayout , RelativeLayout , GridLayout , PercentRelativeLayout ;
- содержится в Support Library, так что баги будут правиться и, возможно, будут появляться новые функции.
- в силу большого количества возможностей уходит больше времени на понимание, как он работает;
- при большом количестве элементов и взаимосвязей между ними сложно проводить код-ревью разметки — иерархическую вложенность контейнеров воспринимать проще, чем большое количество взаимосвязанных элементов в одном контейнере;
- в определенных случаях по производительности может быть хуже иерархии стандартных контейнеров, так как дополнительно требуется время на построение дерева зависимостей;
- несмотря на релизную версию, все еще можно наткнуться на неприятные баги;
- атрибутов у views будет гораздо больше, чем при использовании обычных layouts.
В компании Touch Instinct мы собираемся, как минимум, попробовать этот компонент. Особенно интересно посмотреть, как он поведет себя при использовании в ячейках RecyclerView — там часто изменяются значения элементов, что обычно приводит к пересчету расположения элементов в ячейке и иногда пересчету ее размера.
Разработчики Google проделали большую работу и у ConstraintLayout есть все шансы стать стандартным при разработке элементом UI, какими стали те же RecyclerView и CoordinatorLayout.
Источник