RelativeLayout — суть, правила верстки в Android застосунках

Автор: IT Sectr Опубліковано: 2026-02-24 Час читання: 9 хв

Пояснюємо суть RelativeLayout — ViewGroup в Android SDK для позиціонування дочірніх елементів відносно один одного або відносно батьківського контейнера. На відміну від LinearLayout, який вибудовує елементи строго послідовно, RelativeLayout дозволяє розташувати будь-який елемент ліворуч, праворуч, вище, нижче або по центру відносно будь-якого іншого елемента за його ID. Це робить RelativeLayout зручним для перекривних і складних макетів без вкладеності. Основні правила описані в документації Android Developers.

Головне

  • layout_below / layout_above — прив'язка елемента вище або нижче вказаного елемента за ID; ключові атрибути для побудови потоку.
  • alignParentTop / alignParentBottom — прив'язка краю елемента до відповідного краю батька; працює для всіх чотирьох сторін.
  • Центрування — centerInParent (по центру обох осей), centerHorizontal (по центру по X), centerVertical (по центру по Y).
  • toLeftOf / toRightOf — розміщення елемента ліворуч або праворуч від вказаного елемента, без перекриття.
  • Правила перекриття — якщо правила конфліктують (наприклад, alignParentTop і below іншого), пріоритет має останнє оголошене в XML.

Що таке RelativeLayout?

RelativeLayout — ViewGroup, що з'явилася в Android SDK починаючи з API Level 1, яка позиціонує дочірні елементи через декларативні правила (layout rules) відносно батька або інших дочірніх елементів. Кожне правило задається XML-атрибутом виду android:layout_above, android:layout_below, android:layout_toLeftOf зі значенням ID цільового елемента.

До появи RelativeLayout розробники були змушені використовувати вкладені LinearLayout для кожного нестандартного позиціонування — це призводило до глибокої вкладеності та повільної відмальовки. RelativeLayout вирішив цю проблему, запропонувавши відносне позиціонування на одному рівні ієрархії. Однак його гнучкість обмежена порівняно з сучасним ConstraintLayout: RelativeLayout не підтримує ланцюги, бар'єри, напрямні та відсоткові розміри.

RelativeLayout має дві ключові особливості: один прохід onMeasure (на відміну від LinearLayout з weight, що вимагає двох проходів) та залежність від порядку оголошення — якщо елемент A посилається на елемент B, а B оголошений після A, B повинен мати відомий розмір на момент вимірювання A. Згідно з Android Developers Guide (2024), RelativeLayout виконує вимірювання за один прохід, якщо всі правила посилаються на вже виміряні елементи. В іншому випадку потрібен другий прохід, що знижує продуктивність.

Коли потрібен RelativeLayout

RelativeLayout виправданий для простих макетів з 3–7 елементами, де потрібне відносне позиціонування (надпис над кнопкою, іконка праворуч від тексту, панель внизу екрана). Для нових проєктів рекомендується ConstraintLayout, але RelativeLayout все ще широко використовується в застарілому коді та бібліотеках.

Правила позиціонування: relative та align

RelativeLayout використовує два типи правил: relative-правила (позиціонування відносно іншого елемента) та align-правила (прив'язка до батька). Кожен дочірній елемент може мати необмежену кількість правил, але конфліктуючі правила (наприклад, alignParentTop та below іншого елемента) вирішуються на користь останнього оголошеного атрибута.

Relative-правила: - android:layout_above="@id/target" — нижня межа елемента прив'язана до верхньої межі target. - android:layout_below="@id/target" — верхня межа елемента прив'язана до нижньої межі target. - android:layout_toLeftOf="@id/target" — права межа прив'язана до лівої межі target. - android:layout_toRightOf="@id/target" — ліва межа прив'язана до правої межі target. - android:layout_toStartOf="@id/target" — аналог toLeftOf для RTL-локалізацій. - android:layout_toEndOf="@id/target" — аналог toRightOf для RTL.

Align-правила (до батька): - android:layout_alignParentTop="true" — верхній край елемента збігається з верхнім краєм батька. - android:layout_alignParentBottom="true" — нижній край збігається з нижнім краєм батька. - android:layout_alignParentLeft="true" — лівий край збігається з лівим краєм батька. - android:layout_alignParentRight="true" — правий край збігається з правим краєм батька. - android:layout_alignParentStart та android:layout_alignParentEnd — для RTL.

Align-правила до інших елементів: - android:layout_alignTop="@id/target" — верх елемента збігається з верхом target. - android:layout_alignBottom, android:layout_alignLeft, android:layout_alignRight, android:layout_alignStart, android:layout_alignEnd — аналогічно. - android:layout_alignBaseline="@id/target" — вирівнювання за базовою лінією тексту (корисно для рядків з різними розмірами шрифту).

Центрування та порядок накладання

Центрування в RelativeLayout задається трьома атрибутами: android:layout_centerInParent="true" (по центру батька за обома осями), android:layout_centerHorizontal="true" (по центру по горизонталі) та android:layout_centerVertical="true" (по центру по вертикалі). Центрування сумісне з іншими правилами: елемент може бути відцентрований по горизонталі й при цьому прив'язаний до нижнього краю батька.

Порядок накладання (Z-order) в RelativeLayout визначається порядком оголошення елементів в XML. Перший оголошений елемент малюється першим (буде нижче), останній — останнім (буде вище). Якщо потрібно змінити порядок накладання без зміни XML, використовуйте android:elevation (починаючи з API 21) — елементи з більшою elevation малюються поверх. Для версій нижче API 21 порядок накладання регулюється лише порядком оголошення.

Важливо: RelativeLayout не підтримує атрибут android:elevation для батька — кожен елемент керує своєю elevation самостійно. При конфлікті правил позиціонування та elevation (наприклад, перекривні елементи) elevation має пріоритет для відмальовки, але не для позиціонування — елемент з більшою elevation може візуально перекривати інший, навіть якщо його layout-правила ставлять його «позаду».

Приклади: XML-макети з RelativeLayout

Приклад 1: Профіль користувача

Аватар по центру вгорі, ім'я під аватаром, статус під іменем, кнопка дії внизу екрана. Всі елементи використовують relative-правила для послідовної прив'язки.

xml
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <ImageView
        android:id="@+id/avatar"
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="32dp"
        android:src="@drawable/avatar_placeholder" />

    <TextView
        android:id="@+id/user_name"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/avatar"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="12dp"
        android:text="Іван Іванов"
        android:textSize="20sp"
        android:textStyle="bold" />

    <TextView
        android:id="@+id/user_status"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/user_name"
        android:layout_centerHorizontal="true"
        android:text="Онлайн"
        android:textColor="@color/green" />

    <Button
        android:id="@+id/edit_button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_centerHorizontal="true"
        android:layout_marginBottom="24dp"
        android:text="Редагувати профіль" />

</RelativeLayout>

Аватар прив'язаний до верху через marginTop + centerHorizontal, ім'я — під аватаром через layout_below, статус — під іменем, кнопка — до нижнього краю батька через alignParentBottom. Всі елементи незалежні один від одного, немає ланцюжків та вкладеності.

Приклад 2: Панель з іконкою та бейджем

Іконка з червоним бейджем (кружок з числом) у правому верхньому куті. Бейдж позиціонується відносно іконки через align до її країв з мінусовими margin для накладання.

xml
<RelativeLayout
    android:layout_width="wrap_content"
    android:layout_height="wrap_content">

    <ImageView
        android:id="@+id/icon"
        android:layout_width="48dp"
        android:layout_height="48dp"
        android:src="@drawable/ic_notification" />

    <TextView
        android:id="@+id/badge"
        android:layout_width="20dp"
        android:layout_height="20dp"
        android:layout_alignTop="@+id/icon"
        android:layout_alignRight="@+id/icon"
        android:layout_marginTop="-6dp"
        android:layout_marginRight="-6dp"
        android:gravity="center"
        android:background="@drawable/badge_background"
        android:text="3"
        android:textColor="@android:color/white"
        android:textSize="10sp" />

</RelativeLayout>

Бейдж прив'язаний до верхнього та правого краю іконки. Негативні margin (-6dp) зсувають бейдж назовні, створюючи ефект перекриття межі іконки. Це популярний патерн для сповіщень, який без RelativeLayout потребував би FrameLayout або кастомної відмальовки.

Приклад 3: Екран логіну з RelativeLayout

Форма логіну: логотип по центру вгорі, поле email під ним, поле пароля під email, кнопка «Увійти» під паролем, посилання «Реєстрація» притиснуте до низу. Всі елементи прив'язані послідовно через layout_below.

xml
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="24dp">

    <TextView
        android:id="@+id/logo"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="48dp"
        android:text="MyApp"
        android:textSize="32sp"
        android:textStyle="bold" />

    <EditText
        android:id="@+id/email_input"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/logo"
        android:layout_marginTop="32dp"
        android:hint="Email" />

    <EditText
        android:id="@+id/password_input"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/email_input"
        android:layout_marginTop="16dp"
        android:hint="Пароль"
        android:inputType="textPassword" />

    <Button
        android:id="@+id/login_button"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/password_input"
        android:layout_marginTop="24dp"
        android:text="Увійти" />

    <TextView
        android:id="@+id/register_link"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_centerHorizontal="true"
        android:layout_marginBottom="16dp"
        android:text="Немає акаунта? Зареєструватися"
        android:textColor="@color/primary" />

</RelativeLayout>

Екран використовує 5 елементів на одному рівні ієрархії. Потік зверху вниз (логотип → email → пароль → кнопка) забезпечується через layout_below, а посилання притиснуте до низу через alignParentBottom. Для тієї ж функціональності LinearLayout потребував би два вкладених контейнери (один для верхньої групи, другий для посилання з weight).

RelativeLayout vs ConstraintLayout: порівняння

Порівняння двох ViewGroup для відносного позиціонування: RelativeLayout (класична, API 1+) та ConstraintLayout (сучасна, Jetpack). Критерії: гнучкість, продуктивність, RTL-підтримка та адаптивність.

ХарактеристикаRelativeLayoutConstraintLayout
Відсоткові розміриНі (тільки фіксовані та match_parent)Так (width_percent, height_percent, guideline_percent)
RTL-підтримкаЧерез start/end (API 17+)Вбудована
Chain / ланцюжкиНіТак (spread, spread_inside, packed)
Barrier / Group / FlowНіТак (віртуальні помічники)
MotionLayout анімаціїНіТак
Проходи onMeasure1 (без циклів залежностей)2 (завжди, але оптимізовані)
ЦентруванняcenterInParent, centerHorizontal, centerVerticalЧерез bias (0.0–1.0) з протилежними констрейнтами
Коли використовуватиЗастарілий код, прості макети з 3–7 елементамиНові проєкти, складні екрани, адаптивні макети

RelativeLayout поступається ConstraintLayout практично за всіма параметрами, крім одного: він вбудований в Android SDK з API 1 і не вимагає додаткових залежностей. Для проєктів, які все ще використовують minSdk нижче API 14 (Android 4.0), RelativeLayout — єдиний стандартний варіант відносного позиціонування. В усіх інших випадках Google рекомендує ConstraintLayout.

Часті запитання

Чому елемент RelativeLayout не відображається?

Найімовірніша причина — відсутність достатньої кількості правил позиціонування. Кожен елемент в RelativeLayout повинен мати хоча б одне правило по горизонталі (alignParentLeft, toRightOf, centerHorizontal) і одне по вертикалі (alignParentTop, below, centerVertical). Якщо правил немає, елемент опиняється в позиції (0,0) і може бути прихований під іншими елементами або за межами екрана. Друга причина — циклічна залежність (елемент A прив'язаний до B, B прив'язаний до A), яка призводить до непередбачуваної поведінки.

Як зробити елемент по центру екрана в RelativeLayout?

Використовуйте атрибут android:layout_centerInParent="true". Він центрує елемент за обома осями одночасно. Якщо потрібно тільки по горизонталі — android:layout_centerHorizontal="true", тільки по вертикалі — android:layout_centerVertical="true". Центрування працює в поєднанні з margin — елемент буде зміщений відносно центра на вказаний відступ.

Чи можна використовувати RelativeLayout в RecyclerView?

Можна, але не рекомендується. RelativeLayout виконує два проходи onMeasure за наявності циклічних залежностей, що на 15–30% повільніше за ConstraintLayout у списках RecyclerView. Для item-макетів RecyclerView використовуйте ConstraintLayout — він забезпечує плоску ієрархію з мінімальним часом вимірювання. Якщо RelativeLayout вже використовується в застарілому проєкті, переконайтеся, що елементи не створюють циклічних залежностей, і виміряйте FPS скролу через Profile GPU Rendering.

Чим layout_margin відрізняється від layout_marginTop в RelativeLayout?

android:layout_margin задає відступи з усіх сторін одночасно. android:layout_marginTop — тільки зверху. Пріоритет у більш специфічного атрибута: якщо задані і layout_margin (16dp), і layout_marginTop (8dp), верхній відступ буде 8dp. В RelativeLayout margin працює відносно констрейнта, а не відносно сусіднього елемента: layout_marginTop при layout_below="@id/target" — це відступ від верхньої межі елемента до нижньої межі target.

Підсумки

  • RelativeLayout — ViewGroup для позиціонування елементів відносно один одного або батька через декларативні правила.
  • Правила прив'язки — layout_below/above (вертикаль), layout_toLeftOf/toRightOf (горизонталь), alignParentTop/Bottom (до батька).
  • Центрування — centerInParent (центр), centerHorizontal (по X), centerVertical (по Y) для швидкого вирівнювання.
  • Порядок накладання — визначається порядком оголошення в XML; elevation (API 21+) змінює Z-order при відмальовці.
  • Обмеження — немає відсоткових розмірів, ланцюгів, бар'єрів; циклічні залежності викликають другий прохід onMeasure.
  • Продуктивність — 1 прохід onMeasure без циклів, але поступається ConstraintLayout у складних макетах.
  • Рекомендація — використовуйте в застарілих проєктах; для нових екранів вибирайте ConstraintLayout.

Ми розробимо мобільний застосунок під ключ

IT Sectr створює застосунки для iOS та Android для стартапів і бізнесу з 2017 року. Ми проконсультуємо вас і запропонуємо найкраще рішення.

Обговорити проект

Читайте також