Как задать относительные позиции виджетам в ConstraintLayout
1,00
р.
р.
В ConstraintLayout требуется задать относительное позиционирование вложенных виджетов. Например, Картинка вверху в треть высоты экрана и внизу две кнопки, каждая из которых занимает по половине экрана, чтобы разметка одинаково смотрелась на всех устройствах.
Ответ Верстать данную разметку будем в режиме визуального редактора, так как это нам сильно упростит жизнь в данном случае из-за довольно длинных имен атрибутов, которые использует данный контейнер. Также можно почитать обзорную статью по основным моментам работы с новым визуальным редактором, чтобы изложенное лучше воспринималось. Начинаем работу с того, что задаем две опорные линии. Для этого кликаем правой кнопкой мыши по области редактирования и выбираем Add Vertical Guidline для вертикальной и Add Horizontal Guidline для горизонтальной:
UPD: C Android Studio 2.2 Preview3 опорные линии можно задать из панели инструментов вверху редактора:
Отключаем автоматическое связывание виджетов (подковка вверх с синими концами, в левом верхнем углу, должна быть зачеркнута), так как эта функция не всегда хорошо понимает, что хочет человек. По умолчанию опорная линия позиционируется по относительным координатам (расстоянию в dp), о чем сообщает изображение стрелочки в кружочке этой линии. Но нам нужно относительное позиционирование в процентах, поэтому кликаем мышкой на эту стрелочку в кружочке и она приобретает вид с процентами - двигаем за этот кружочек в нужные позиции: вертикальную устанавливаем в 50%, а горизонтальную устанавливаем в 34% (треть экрана), затем бросаем на разметку три виджета, которые нам нужны (ImageView и две Button):
Теперь привязываем к этим линиям наши виджеты, кликаем на виджет и соединяем кружочки на их гранях с привязочными линиями: кнопки - левую кнопку с левого края с краем экрана и нижнюю точку с низом экрана, правый кружок с вертикальной опорной линией, правую кнопку так же, только в зеркально (UPD С версии 1.0 появился режим компоновки chains (цепочки), который позволяет обойтись без вертикальной опорной линии):
Размер кнопкам по горизонтали назначаем - максимальное расстояние (аналог match_parent), в квадрате справа щелкаем по горизонтальным линиям, пока не появится в виде "пилы" - . (треугольнички - wrap_content, отрезок - фиксированный размер). Вертикальный оставляем, как есть (в виде треугольничков - wrap_content). Задаем маржины, числа сбоку от пиктограмм размера виджета (здесь 16dp и 8dp). С кнопками все. Теперь нижний край (кружок снизу) у ImageView соединяем с горизонтальной опорной линией. Прочие края соединяем с краями экрана:
ставим маржины у ImageView в 0, размер виджета wrap_content:
Вот и все. Описание получилось очень длинным, но в реальности эта верстка заняла меньше минуты. В итоге получаем следующее:
Данная разметка будет сохранять свой относительный вид на любых размерах экранов с любой плотностью. Так же следует заметить, что ConstraintLayout предпочтительнее RelativeLayout, так как гораздо лучше оптимизирован и рассчитывается быстрее, кроме того имеет больше возможностей по позиционированию. Например, в данной разметке пришлось бы вообще использовать несколько вложенных "классических" контейнеров. Если виджету требуется указать дополнительные свойства, то кликаем на пиктограмму разнонаправленных стрелочек в верхнем правом углу редактора - появятся все атрибуты, доступные для виджета:
Google сделал анимированную презентацию нового инструмента, посмотрев которую, можно освоить основные моменты работы. в xml-виде все это выглядит следующим образом: