- Layout интерфейса приложения Android
- Привязка компонента в ConstraintLayout
- Как добавить привязки?
- «Привязка» компонентов между собой
- Удаление привязки
- Исходный текст activity_main.xml
- Шаблон LinearLayout
- ConstraintLayout
- Aspect ration (Соотношение сторон)
- GuideLine
- Chains — Скованные одной цепью
- Проценты
- Barriers
- Groups
- Анимация
- Circular
- Placeholder
- ConstraintLayoutStates (2.0.0)
- res/layout/activity_cl_states_start.xml
- res/layout/activity_cl_states_loading.xml
- res/layout/activity_cl_states_end.xml
- res/xml/constraint_layout_states.xml
- Layer
- Другие атрибуты
- Примеры
- Обновления
Layout интерфейса приложения Android
В приложении Android контейнер компонентов имеет тип ViewGroup. Существует несколько разновидностей классов, наследующих свойства ViewGroup и определяющих структуру расположения компонентов в интерфейсе : LinearLayout, RelativeLayout, FrameLayout, TableLayout, ConstraintLayout и т.д. Отличия этих классов связаны с упорядочиванием компонентов :
• ConstraintLayout | позволяет привязывать компонент к границам экрана или к другим компонентам. |
• LinearLayout | позволяет размещать View-компоненты в виде одной строки (horizontal) или одного столбца (vertical). |
• RelativeLayout | настраивает положение каждого компонента относительно других. |
• AbsoluteLayout | использует для каждого компонента явную позицию на экране в системе координат X, Y. |
• TableLayout | отображает элементы в виде таблицы, по строкам и столбцам. |
Рассмотрим вопрос привязки компонентов в ConstraintLayout. Для этого создадим новое приложение p02layout по типу и подобию, описанному на странице Модули Android.
Привязка компонента в ConstraintLayout
Во вновь созданном проекте p02layout откроем модуль activity_main.xml в режиме Design и удалим включаемый по умолчанию компонент TextView с текстом «Hello World!», поскольку ему не требуется привязка; она создана студией. После этого добавим новый компонент TextView из палитры (Pallete) в интерфейс окна.
Если переключиться на текстовое представление модуля activity_main.xml, то можно сразу же увидить, что :
- в качестве контейнера компонентов студия использовала при создании приложения ConstraintLayout;
- компонент TextView подчеркнут красной линией.
При наведении на TextView мышкой во всплывающей подсказке Android Studio покажет ошибку :
This view is not constrained, it only has designtime positions, so it will jump to (0,0) unless you add constraints.
Этим сообщением IDE подсказывает нам, что компонент не «привязан», и его текущее положение в интерфейсе актуально только на время разработки. А при старте приложения положение компонента будет проигнорировано, и View переместится в точку (0,0), т.е. в верхний левый угол. Чтобы зафиксировать положение View в определенном месте ConstraintLayout необходимо добавить привязки (constraints). Они будут задавать положение View на экране относительно каких-либо других элементов или относительно родительского View.
Как добавить привязки?
Если выделить на экране TextView, то можно увидеть 4 круга по его сторонам. Эти круги используются для привязки компонента по горизонтали и вертикали. Напоминаю, что контейнер ConstraintLayout занимает весь экран и его края совпадают с краями экрана, а также он является родителем TextView.
Чтобы привязать компонент к левой стороне экрана по горизонтали выделите его левой кнопкой мыши, после этого тащите левый круг к левой границе экрана. Как только стрелка коснется левой границы экрана, то компонент также сразу же переместиться к левой стороне экрана. Изображение курсора меняется в зависимости от нахождения курсора на компоненте, перемещения круга или перемещения компонента.
После этого необходимо «схватить» компонент левой клавишей мыши и переместить вправо на требуемую величину (нижний скриншот). Обратите внимание на число под стрелкой, которое меняется при перемещении компонента. Это величина отступа TextView от объекта, к которому он привязан; в нашем случае от левой границы родителя ConstraintLayout.
Теперь, Вам не составит труда привязать компонент к верхней границе экрана. Для этого необходимо повторить предыдущую операцию, но только уже с верхней стороной компонента.
Примечание : привязка компонента изображается на экране в виде прямой сплошной линии. Но если сделать двустороннюю привязку по горизонтали или вертикали, т.е. привязать компонент, например, к левой и правой сторонам экрана, то привязки будут изображены на экране в виде пружины.
«Привязка» компонентов между собой
Компоненты можно привязывать не только к границам родителя, но и к другим View. Связанные между собой компоненты перемещаются по экрану вместе. То есть, перемещение главного компонента в новую позицию формы автоматически переместит и связанные с ним другие компоненты.
Давайте разместим в интерфейсе новый компонент типа PlainText и привяжем его к компоненту TextView. Компоненты связываются между собой также соответствующими кругами на сторонах. Как только вы подводите стрелку «дочернего» компонента к «родительскому», то студия подсветит у родителя его круги. Останется только совместить стрелку с кругом. После этого можно привязанный компонент перетаскивать и менять его относительное удаление.
Удаление привязки
Чтобы удалить привязку, необходимо просто нажать на соответствующий кружок компонента.
Исходный текст activity_main.xml
Исходный текст включает описания двух компонентов. Главный тег описания макета интерфейса представлен типом android.support.constraint.ConstraintLayout. Идентификатор компонента в описании обозначается атрибутом android:id. Остальные параметры (атрибуты) определяют размеры, относительные положения и специфические свойства компонента.
На следующем скриншоте представлен интерфейс работающего приложения. При вводе в текстовую строку PlainText символов устройство Android (эмулятор) открыл панель клавиатуры и высветил подсказки.
Шаблон LinearLayout
Прежде чем переходить к линейному макетированию компонентов заглянем в основной класс приложения MainActivity.java.
Класс MainActivity.java имеет метод onCreate, который вызывается, когда приложение создает и отображает Activity. В первой строке метода происходит обращение к суперклассу. А вот во второй строке метод setContentView(int) фоормирует интерфейс Activity из layout-файла. В качестве аргумента методу передается не путь к layout-файлу (res/layout/activity_main.xml), а идентификатор файла ID.
Создадим новый layout. Для этого выберем пункт меню New => XML => Layout XML file. Любители горячих клавиш могут использовать второй способ : при выделенной папке res/layout нажать ALT+Insert, и там уже клавишами выбрать соответствующий пункт.
Во вновь открывшемся окне необходимо определить наименование XML-файла макетирования интерфейса и выбрать тип (Root Tag).
После определения имени linear в папке layout должна появиться новая запись (linear.xml). Все файлы XML, связанные с настройкой интерфейса, размещаются в директории приложения res/layout.
Теперь откроем файл linear.xml в режиме Design и разместим в интерфейсе три кнопки. При перетаскивании первой кнопки, Вы увидете, что она заняла весь экран по ширине. После перетаскивания второй кнопки размер первой уменьшился наполовину. И так далее. На скриншоте можно увидеть положения кнопок в интерфейсе. Кроме этого, в панели дерева (Component Tree) родителем кнопок является контейнер LinearLayout.
В исходном коде файла linear.xml (вкладка Text) можно посмотреть описание интерфейса :
Положение с горизонтального без каких-либо проблем можно изменить на вертикальное. Для этого следует либо в тексте файла linear.xml переопределить атрибут «android:orientation» на «vertical», либо в панели атрибутов установить соответствующее значение, как это представлено на скриншоте.
Чтобы стартовать приложение с шаблоном интерфейса linear.xml необходимо в метод onCreate класса MainActivity.java внести изменения во вторую строку : setContentView(R.layout.linear). Интерфейс работающего приложения с линейным контейнером расположения компонентов LinearLayout представлен на скриншоте.
Если Вы полностью самостоятельно повторили все действия, связанные с привязками компонентов в контейнерах типа ConstraintLayout и LinearLayout, то Вам не составит труда выполнить подобные действия с контейнерами RelativeLayout и AbsoluteLayout.
Продолжение статьи с табличным расположением компонентов TableLayout представлено здесь.
Источник
ConstraintLayout
Новый макет ConstraintLayout появился в Android Studio 2.2 и доступен для устройств с версии Android 2.3. Его можно найти в разделе Layouts. Гугл очень расхваливает данный макет и советует всем переходить на него и даже создал специальный конвертер для этой задачи. Если у вас имеется старый проект, то достаточно щёлкнуть правой кнопкой мыши на корневом элемента макета и выбрать пункт Convert layout to ConstraintLayout. В диалоговом окне ничего не трогаем.
В build.gradle модуля прописывается ссылка на библиотеку и проект начинает синхронизироваться. Сейчас уже активно развивается ветка 2.х.x, лучше сразу переходить на неё.
В Android Studio 2.3 и выше в шаблонах по умолчанию теперь используется ConstraintLayout.
Если в режиме дизайна выбран данный компонент, то на панели инструментов вам доступны несколько кнопок.
- View Options с пунктами Show Constraints — выводит заданные ограничения в режимах предварительного просмотра и раскладки. В одних случаях этот режим просмотра полезен, в других нет. При большом количестве ограничений эта кнопка выводит слишком много информации, Show Margins, Fade Unselected views.
- Turn On Autoconnect — при включении режима Autoconnect ограничения будут автоматически настраиваться при перетаскивании представлений в область предварительного просмотра. Студия старается угадать, какие ограничения должен иметь компонент, и создавать их по мере необходимости
- Default Margins — стандартное значение для отступов. Можете устанавливать отдельно для каждого компонента. Выбрали компонент, установили значение, затем снова выбрали другой компонент и установили другое значение
- Clear All Constraints — удаляет все ограничения из макета
- Infer Constraints — автоматически создаёт ограничения. Срабатывает только при нажатии кнопки. Функциональность Autoconnect срабатывает каждый раз, когда в файл макета добавляется новый компонент
- GuideLines с двумя опциями: Add Vertical GuideLine и Add Horizontal GuideLine. Смотри ниже
Очень часто на форумах встречается вопрос, почему в режиме дизайна макет выглядит хорошо, а при запуске приложения все компоненты сбиваются в верхний левый угол. Для решения этой проблемы попробуйте нажать на кнопку Infer Constraints, которая создаст дополнительные ограничения.
ConstraintLayout является наследником ViewGroup и местами похож на RelativeLayout, но более продвинут. Код разметки в XML-представлении:
Управление компонентами внутри данного контейнера достаточно сильно отличается от старого взаимодействия. Придётся всем переучиваться.
При его использовании нет смысла использовать XML-представление, только в режиме Design, когда вы можете подвигать все компоненты в визуальном редакторе.
Рассмотрим отдельные элементы, которые используются для редактирования макета. Переключитесь в режим Blueprint, чтобы ничего нас не отвлекало от работы.
Так выглядит выбранный компонент.
Квадратные опорные точки в углах компонента позволяют изменять его размеры. Круглые опорные точки по краям позволяют управлять отступами от краёв экрана и других компонентов.
Продолговатый закругленный прямоугольник указывает на базовую линию текста. Пригодится при выравнивании по базовой линии другого компонента.
Также можно увидеть зигзагообразные направляющие-пружинки, которые нужны для особых случаев. Если провести мышкой над опорной точкой пружинки, она красиво активируется. Последующий щелчок удаляет пружинку. Если компонент удерживался двумя пружинками сверху и снизу, то удаление одной из них притянет компонент к верхней или нижней части экрана. Лучше самостоятельно проверить у себя, так как словами трудно описать.
Пружинки также можно легко восстановить, если щёлкнуть по круглой опорной точке и потянуть её к краю экрана.
Наверху на панели инструментов можно активировать автоматический режим размещения компонентов Autoconnect в виде магнита . В этом случае вы просто бросаете на экран нужный компонент, а далее студия сама пытается найти нужные параметры для него. Всё это происходит с красивой анимацией. Естественно, вы можете всё переиграть и поставить в нужную позицию.
На той же панели есть инструмент Infern Constraints в виде пары звёздочек . Действует как Autoconnect, только работает не с одним компонентом, редактируемым в данный момент, а со всем макетом сразу, используя математические расчёты, чтобы определить, какие компоненты нужно привязать к другим, исходя из их местоположения на экране.
Теперь рассмотрим настройки в панели Properties.
Набор из трёх стрелок внутри квадрата означают атрибут wrap_content. Если вы измените этот атрибут с помощью выпадающего списка или вручную напишите размер в dp, то увидите, что стрелки заменятся на прямые (фиксированный размер
) или пружинку (match_constraints
, который является приблизительным аналогом атрибута match_parent и имеет значение 0dp).
По бокам квадрата имеются числа. Если подвести к ним мышку, то появится выпадающий список с определёнными значениями: 0, 8, 16, 24, 32. Они отвечают за атрибут margin (отступы).
По бокам можно увидеть также ползунки с числами в кружочке. В примере виден только горизонтальный ползунок, при других настройках увидите и вертикальный. С их помощью можно центрировать компонент относительно экрана и других объектов.
Aspect ration (Соотношение сторон)
Если у компонента есть двусторонняя вертикальная привязка и значение высоты установлено в match_constraints (0dp), то можно настроить так, чтобы высота зависела от ширины. В углу появится треугольник, щёлкнув на котором можно затем установить желаемое соотношение. Потом можно изменять ширину, чтобы увидеть, как высота подстраивается под ширину.
Аналогично можно настроить зависимость ширины от высоты, предварительно сначала установив двустороннюю горизонтальную привязку.
GuideLine
На панели инструментов также имеется значок GuideLines с двумя опциями: Add Vertical GuideLine и Add Horizontal GuideLine. Если ими воспользоваться, то в XML-файле появятся такие строчки:
По сути, это View, размер которого 0, что соответствует View.GONE. На этапе разработки мы видим только полоски, а во время работы приложения ничего не видим. Данные элементы помогают разместить компоненты аккуратно относительно линии.
Направляющие пригодятся, если одни и те же значения отступов повторяются для нескольких компонентов. Направляющие можно указывать в dp от края экрана или задать в процентах от ширины экрана. Чтобы переключаться между разными режимами, вы можете нажать на круглый значок Guideline.
Не всегда с помощью визуального редактора можно добиться нужного результата, тогда нужно переключиться в XML-режим. Один из таких случаев описан в статье Square Island: Constraint Layout: Icon Label Text.
Если есть желание работать через XML, то следует запомнить очень много атрибутов, например, для выравнивания относительно друг друга:
- app:layout_constraintStart_toStartOf=»@id/view»
- app:layout_constraintLeft_toLeftOf=»@id/view»
- app:layout_constraintEnd_toEndOf=»@id/view»
- app:layout_constraintRight_toRightOf=»@id/view»
- app:layout_constraintTop_toTopOf=»@id/view»
- app:layout_constraintBaseline_toBaselineOf=»@id/view»
- app:layout_constraintBottom_toBottomOf=»@id/view»
- app:layout_constraintStart_toEndOf=»@id/view»
- app:layout_constraintLeft_toRightOf=»@id/view»
- app:layout_constraintEnd_toStartOf=»@id/view»
- app:layout_constraintRight_toLeftOf=»@id/view»
- app:layout_constraintTop_toBottomOf=»@id/view»
- app:layout_constraintBottom_toTopOf=»@id/view»
Атрибут app:layout_constraintHorizontal_bias используется float-значения от 0 до 1, для выравнивания по оси.
Атрибут app:layout_constraintDimensionRatio=»4:3″ указывает, что нужно использовать данные пропорции по высоте и ширине для данного компонента. Также встречается модификация атрибута app:layout_constraintDimensionRatio=»H, 1:1″.
Chains — Скованные одной цепью
Несколько элементов можно сковать одной цепью. Допустим, у нас есть три кнопки. Выделяем их и через контекстное меню выбираем Center Horizontally. Снизу у выбранных компонентов появится символ цепи, а между ними будут нарисована связь в виде цепей. Если последовательно щёлкать по значку цепи, то увидите, как кнопки будут центрироваться с разными стилями:
- spread — Свободное пространство равномерно распределяется между выбранными компонентами и краями родителя (например, экрана)
- spread_inside — Крайние компоненты прижимаются к границам родителя, свободное пространство равномерно распределяется только между остальными компонентами
- packed — Свободное пространство равномерно распределяется между крайними компонентами и границами родителя. Вы можете использовать margin для отступов
За цепи отвечают стили.
- app:layout_constraintHorizontal_chainStyle=»spread»
- app:layout_constraintVertical_chainStyle=»spread»
- app:layout_constraintHorizontal_chainStyle=»spread_inside»
- app:layout_constraintVertical_chainStyle=»spread_inside»
- app:layout_constraintHorizontal_chainStyle=»packed»
- app:layout_constraintVertical_chainStyle=»packed»
Также можно присвоить кнопкам вес, когда одна кнопка может быть больше остальных, это поведение знакомо по LinearLayout. Для этих целей используются атрибуты
Как и в LinearLayout, чтобы использовать вес, надо поставить размер компонента в 0dp.
На рисунке этот вариант представлен в третьем примере.
Проценты
Можно указывать значения ширины и высоты в процентах через атрибуты layout_constraintWidth_percent, layout_constraintHeight_percent. Все View-компоненты поддерживают данные атрибуты. Они позволяют ограничить компонент процентным значением в рамках всего доступного пространства. Например, мы хотим видеть кнопку, которая будет занимать 70% в рамках свободного для неё места.
Barriers
Barriers — это виртуальный View, который используется как шаблон. Он применяется для нескольких компонентов неизвестного размера – если один из них увеличивается, то барьер подстроит размер остальных под наибольшую высоту или ширину. Барьеры могут быть вертикальными и горизонтальными и создаваться сверху, снизу, слева или справа от нужных элементов. Другие элементы будут подстраиваться.
Барьеры полезны, когда вы создаёте локализованные строки или отображаете контент, созданный пользователем, размер которого вы не можете предсказать.
Groups
Groups — теперь можно логически группировать определённые виды. По сути, это некий контейнер, который содержит ссылки на ID компонентов, а не сами компоненты. При помощи группы вы можете установить видимость всех компонентов в контейнере. Это может пригодиться, когда сразу несколько элементов должны изменять свою видимость или другие свойства.
Анимация
Для анимации разметки ConstraintLayout используется ConstraintSet.
Circular
С помощью Circular мы можем настроить два компонента так, чтобы одно находилось на определённом расстоянии и под определённым углом от другого.
- layout_constraintCircle — указываем идентификатор компонента, который будет центром окружности
- layout_constraintCircleRadius — расстояние от центра окружности до компонента
- layout_constraintCircleAngle — угол (в градусах, от 0 до 360)
При создании круговых зависимостей углы начинаются сверху и изменяются по часовой стрелке. Например, таким образом нужно описать среднюю кнопку в примере выше:
Такой способ пригодится для анимации аналоговых часов или похожих примеров.
Placeholder
Элемент Placeholder позволяет использовать место на экране в качестве временного заполнителя. Используя анимацию, можно динамически перемещать компонент на место заполнителя.
ConstraintLayoutStates (2.0.0)
В ветке 2.х появилась новая функциональность — переключение между макетами экрана. Это удобно, когда требуются небольшие изменения на одном экране. Вы должны создать несколько макет с одинаковыми компонентами, но при этом можете изменить их свойства (видимость, местоположение и т.д). В нужный момент программно переключаетесь на нужный макет.
Создадим три разных макета в папке layout.
res/layout/activity_cl_states_start.xml
res/layout/activity_cl_states_loading.xml
res/layout/activity_cl_states_end.xml
В нашем примере во всех макетах имеются ProgressBar и Button с разной видимостью и позицией.
Следующий шаг — создать в папке res/xml новый файл, описывающий три созданных макета.
res/xml/constraint_layout_states.xml
Осталось написать программную часть. Сначала мы загружаем первый макет в стандартном методе setContentView(). Затем загружаем описания созданных нами макетов через loadLayoutDescription() объекта-контейнера нашего ConstraintLayout. Теперь мы можем переключаться между макетами через constraintLayout.setState().
В примере при нажатии кнопки мы имитируем долгоиграющую задачу и выводим ProgressBar, когда задача будет завершена, то выводим третий макет, где кнопка находится уже в другом месте.
В версии 2.0.0-alpha5 появился новый вид виртуального макета Flow, который позволяет работать с объектами разных размеров.
Layer
Новый виртуальный помощник Layer работает с группой компонентов, применяя к ним различные трансформации: вращение, перемещение, масштабирование.
Другие атрибуты
Стоит обратить внимание на следующие атрибуты. Они часто используются, если в контейнере содержится компонент RecyclerView.
- android:background=»?android:attr/selectableItemBackground»
- android:clickable=»true»
- android:focusable=»true»
Примеры
Стандартный случай: картинка и две текстовые метки. Верхней край картинки должен совпадать с верхней частью первой строки, а нижний край картинки с нижней частью второй строки. При этом картинка векторная и должна сохранять пропорции. Макет при изменении размера шрифта должен сохранять свою структуру.
Обновления
Библиотека постоянно развивается. Некоторые пункты меню были переработаны и изменены. Следите за изменениями.
Источник