Android Studio: урок Kotlin — ConstraintLayout для гибкой вёрстки

Правильное расположение кнопок, текста и изображений — основа любого интерфейса. В Android главный инструмент для этого сегодня — ConstraintLayout, который пришёл на смену вложенным LinearLayout и RelativeLayout. Он позволяет строить сложные экраны с минимумом вложенности, что заметно ускоряет отрисовку. Сегодня в Android Studio мы разберём, как с помощью языка Kotlin и этого контейнера создать адаптивный макет, который одинаково хорошо выглядит на разных устройствах. Материал этого урока подойдёт тем, кто только начинает знакомство с вёрсткой.


Зачем нужен ConstraintLayout

Представьте, что вы хотите разместить три кнопки: одну слева вверху, вторую по центру экрана и третью справа внизу. С LinearLayout пришлось бы вкладывать несколько контейнеров друг в друга, а с RelativeLayout — описывать относительные позиции. ConstraintLayout делает это гораздо проще: вы задаёте связи (constraints) между элементами и краями родителя, и система сама вычисляет их положение. Это позволяет создать сложный макет с плоской иерархией, что положительно сказывается на производительности.


Добавление ConstraintLayout в проект

ConstraintLayout входит в библиотеку AndroidX и обычно уже присутствует в новых проектах. Если по каким-то причинам его нет, откройте build.gradle.kts уровня модуля app и добавьте строку:

dependencies {
    implementation("androidx.constraintlayout:constraintlayout:2.2.0")
}

После синхронизации Gradle компонент можно использовать в разметке.


Разметка экрана с привязками

В файле activity_main.xml замените корневой элемент на ConstraintLayout. Добавим три кнопки и настроим связи. Каждый элемент должен быть привязан хотя бы к одному вертикальному и одному горизонтальному краю, иначе он «прилипнет» к верхнему левому углу.

<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <Button
        android:id="@+id/btnTopLeft"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Вверху слева"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        android:layout_margin="16dp" />

    <Button
        android:id="@+id/btnCenter"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Центр"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent" />

    <Button
        android:id="@+id/btnBottomRight"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Внизу справа"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        android:layout_margin="16dp" />
</androidx.constraintlayout.widget.ConstraintLayout>

Центрирование элемента выполняется установкой всех четырёх привязок к соответствующим сторонам родителя. Если привязать только сверху и снизу, элемент окажется по центру по вертикали, но останется прижатым к левому краю — для горизонтального центрирования нужны ещё левая и правая привязки.


Связи между элементами

Привязывать элементы можно не только к родителю, но и друг к другу. Например, разместим TextView под первой кнопкой, используя app:layout_constraintTop_toBottomOf="@id/btnTopLeft". Это создаст цепочку зависимостей, при которой сдвиг одной кнопки автоматически сместит связанный с ней элемент.

<TextView
    android:id="@+id/tvUnderButton"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Я под кнопкой"
    app:layout_constraintTop_toBottomOf="@id/btnTopLeft"
    app:layout_constraintStart_toStartOf="@id/btnTopLeft"
    android:layout_marginTop="8dp" />

Работа с Guideline

Guideline — это невидимая вспомогательная линия, которая помогает выравнивать элементы без привязки к конкретному View. Её можно задать в процентах от ширины экрана или в dp. Например, вертикальная линия на 30% экрана слева.

<androidx.constraintlayout.widget.Guideline
    android:id="@+id/guideline"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    app:layout_constraintGuide_percent="0.3" />

Теперь любой элемент можно привязать к этой линии: app:layout_constraintStart_toEndOf="@id/guideline". Это удобно для адаптивных макетов, где позиции должны зависеть от ширины экрана, а не от фиксированных отступов.


Программное управление привязками

Иногда связи нужно изменить динамически из Kotlin-кода. Для этого используется класс ConstraintSet. Создаём новый набор привязок, клонируем существующие, меняем то, что нужно, и применяем к макету.

val constraintSet = ConstraintSet()
constraintSet.clone(constraintLayout)
constraintSet.connect(
    R.id.btnCenter,
    ConstraintSet.START,
    ConstraintSet.PARENT_ID,
    ConstraintSet.END
)
constraintSet.applyTo(constraintLayout)

Этот код перемещает центральную кнопку вправо, сохраняя вертикальное центрирование. ConstraintSet позволяет менять привязки без пересоздания разметки, что гораздо быстрее.


Полезные советы

  • Используйте визуальный редактор. На вкладке Design у ConstraintLayout есть удобный drag-and-drop интерфейс с панелью привязок. Для начала это быстрее, чем писать XML вручную.
  • Не оставляйте элементы без привязок. Если у View нет хотя бы одной горизонтальной и одной вертикальной связи, при запуске он окажется в позиции (0,0). Всегда проверяйте, что все направления привязаны.
  • Помните про chains. Цепочки позволяют группировать несколько элементов и распределять пространство между ними равномерно. Для этого привяжите элементы друг к другу и установите app:layout_constraintHorizontal_chainStyle="spread" на первом элементе.

Коротко о главном

Этот урок в Android Studio на Kotlin показал, как с помощью ConstraintLayout строить гибкие и производительные макеты. Вы научились привязывать элементы к краям экрана и друг к другу, центрировать их и использовать вспомогательные линии. Теперь ваши интерфейсы будут выглядеть одинаково хорошо на телефонах с разными размерами экранов. Попробуйте переделать свой текущий проект на ConstraintLayout — вы сразу заметите, насколько меньше стало вложенных контейнеров.

Яндекс.Метрика