ConstraintLayout

Последнее обновление: 14.10.2021

ConstraintLayout представляет контейнер, который позволяет создавать гибкие и масштабируемые визуальные интерфейсы.

Для позиционирования элемента внутри ConstraintLayout необходимо указать ограничения (constraints). Есть несколько типов ограничений. В частности, для установки позиции относительно определенного элемента испльзуются следующие ограничения:

  • layout_constraintLeft_toLeftOf: левая граница позиционируется относительно левой границы другого элемента

  • layout_constraintLeft_toRightOf: левая граница позиционируется относительно правой границы другого элемента

  • layout_constraintRight_toLeftOf: правая граница позиционируется относительно левой границы другого элемента

  • layout_constraintRight_toRightOf: правая граница позиционируется относительно правой границы другого элемента

  • layout_constraintTop_toTopOf: верхняя граница позиционируется относительно верхней границы другого элемента

  • layout_constraintTop_toBottomOf: верхняя граница позиционируется относительно нижней границы другого элемента

  • layout_constraintBottom_toBottomOf: нижняя граница позиционируется относительно нижней границы другого элемента

  • layout_constraintBottom_toTopOf: нижняя граница позиционируется относительно верхней границы другого элемента

  • layout_constraintBaseline_toBaselineOf: базовая линия позиционируется относительно базовой линии другого элемента

  • layout_constraintStart_toEndOf: элемент начинается там, где завершается другой элемент

  • layout_constraintStart_toStartOf: элемент начинается там, где начинается другой элемент

  • layout_constraintEnd_toStartOf: элемент завершается там, где начинается другой элемент

  • layout_constraintEnd_toEndOf: элемент завершается там, где завершается другой элемент

Возможно, по поводу четырех последних свойств возникло некоторое непонимание, что подразумевается под началом или завершением элемента. Дело в том, что некоторые языки (например, арабский или фарси) имеют правостороннюю ориентацию, то есть символы идут справа налево, а не слева направо, как в европейских языках. И в зависимости от текущей ориентации - левосторонняя или правосторонняя - будет изменяться то, где именно начало, а где завершение элемента. Например, при левосторонней ориентации начало - слева, а завершение - справа, поэтому атрибут layout_constraintStart_toEndOf фактически будет аналогичен атрибуту layout_constraintLeft_toRightOf. А при правосторонней ориентации - атрибуту layout_constraintRight_toLeftOf, так как начало справа, а завершение - слева

Каждое ограничение устанавливает позиционирование элемента либо по горизонтали, либо по вертикали. И для определения позиции элемента в ConstraintLayout необходимо указать как минимум одно ограничение по горизонтали и одно ограничение по вертикали.

Позиционирования может производиться относительно границ самого контейнера ContentLayout (в этом случае ограничение имеет значение parent), либо же относительно любого другого элемента внутри ConstraintLayout, тогда в качестве значения ограничения указывается id этого элемента.

Простейший пример:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!"
        android:textSize="30sp"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

В данном случае у элемента TextView установлено два ограничение: одно погоризонтальной линии (app:layout_constraintLeft_toLeftOf="parent"), второе - по вертикальной линии (app:layout_constraintTop_toTopOf="parent"). Оба ограничения устанавливаются относительно контейнера ConstraintLayout, поэтому они принимают значение parent, то есть ConstraintLayout.

Ограничение app:layout_constraintLeft_toLeftOf="parent" устанавливает левую границу TextView у левой границы контейнера.

Ограничение app:layout_constraintTop_toTopOf="parent" устанавливает верхнюю границу TextView у верхней границы контейнера.

В итоге TextView будет располагаться в верхнем левом углу контейнера.

Расположение элементов в ConstraintLayout в Android Studio

Стоит обратить внимание, что все эти атрибуты ограничений берутся из пространства имен "http://schemas.android.com/apk/res-auto", которое проецируется на префикс app.

Если необходимо установить ограничение относительно другого элемента, то необходимо указать id этого элемента:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <EditText
        android:id="@+id/editText"
        android:layout_width="180dp"
        android:layout_height="wrap_content"
        android:hint="Введите Email"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Отправить"
        app:layout_constraintLeft_toRightOf="@id/editText"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

Здесь для текстового поля ввода EditText устанавливаются два ограничения относительно родительского контейнера ConstraintLayout, поэтому ограничения имеют значение parent, а сам EditText выравнивается по левой и верхней границе контейнера. Верхняя граница кнопки Button также выравнивается по верхней границе контейнера. А вот левая граница кнопки выравнивается по правой границе EditText. Для этого в качестве значения атрибута передается id EditText:

app:layout_constraintLeft_toRightOf="@id/editText"
Позиционирование в ConstraintLayout в Android

Подобным образом можно составлять различные комбинации атрибутов для определения нужного нам позиционирования. Например, изменим код кнопки:

<Button
	android:id="@+id/button"
	android:layout_width="wrap_content"
	android:layout_height="wrap_content"
	android:text="Отправить"
	app:layout_constraintLeft_toRightOf="@id/editText"
	app:layout_constraintTop_toBottomOf="@id/editText" />

В данном случае верхняя граница кнопки выравнивается по нижней границе EditText

Позиционирование в ConstraintLayout в Android

Более того мы можем позиционировать оба элемента один относительно другого:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <EditText
        android:id="@+id/editText"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:hint="Введите Email"
        app:layout_constraintRight_toLeftOf="@+id/button"
        app:layout_constraintTop_toTopOf="parent" />
    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Отправить"
        app:layout_constraintLeft_toRightOf="@id/editText"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

Позиционирование в центре

Если необходимо расположить элемент в центре контейнера по вертикали, то надо использовать пару атрибутов

app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"

Если необходимо расположить элемент в центре контейнера по горизонтали, то надо использовать следующую пару атрибутов

app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"

Соответственно для расположения в центре контейнера по вертикали и горизонтали надо применить все выше указанные четыре атрибута:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello Android"
        android:textSize="30sp"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toBottomOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>
Позиционирование в центре ConstraintLayout в Android

Сдвиг

Если элементы расположены по центру, ConstraintLayout позволяет их сдвигать по горизонтали и по вертикали. Для сдвига по горизонтали применяется атрибут layout_constraintHorizontal_bias, а для сдвига по вертикали - атрибут layout_constraintVertical_bias. В качестве значения они принимают число с плавающей точкой от 0 до 1. Значение по умолчанию - 0.5 (расположение по центру). Например:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Top TextView"
        android:textSize="30sp"
        android:background="#e0e0e0"

        app:layout_constraintHorizontal_bias="0.2"

        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"/>

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Bottom TextView"
        android:textSize="30sp"
        android:background="#e0e0e0"

        app:layout_constraintHorizontal_bias=".9"

        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"/>

</androidx.constraintlayout.widget.ConstraintLayout>

Первый TextView сдвигается на 20% от левой границы контейнера (значение по умолчанию - 0.5, поэтому при значении 0.2 элемент сдвигается влево). Второй TextView сдвигается на 90% от левой границы контейнера. Например, значение 1 означало бы, что элемент придвинут к правой границе, а значение 0 - к левой

Bias сдвиг элементов и виджетов в ConstraintLayout в Android Studio

Аналогично работает атрибут layout_constraintVertical_bias, который сдвигает по вертикали.

Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850