RelativeLayout — Android SDK-dagi, bolak elementlarni bir-biriga yoki ota-ona konteynerga nisbatan joylashtirish uchun ViewGroup. LinearLayout dan farqli o'laroq, elementlarni qat'iy ketma-ket joylashtiradi, RelativeLayout istalgan elementni ID si bo'yicha boshqa elementning chapida, o'ngida, yuqorisida, pastida yoki markazida joylashtirishga imkon beradi. Bu RelativeLayout ni ichma-ich joylashtirishsiz bir-birining ustiga chiqadigan va murakkab maketlar uchun qulay qiladi. Asosiy qoidalar Android Developers hujjatlarida tasvirlangan.
Asosiy fikrlar
RelativeLayout — API Level 1 dan boshlab Android SDK da mavjud bo'lgan, bolak elementlarni deklarativ qoidalar (layout rules) orqali ota-onaga yoki boshqa bolak elementlarga nisbatan joylashtiradigan ViewGroup. Har bir qoida android:layout_above, android:layout_below, android:layout_toLeftOf kabi XML atributi bilan maqsadli elementning ID si ko'rsatilgan holda belgilanadi.
RelativeLayout paydo bo'lishidan oldin dasturchilar har bir nostandart joylashtirish uchun ichma-ich LinearLayout lardan foydalanishga majbur edilar — bu chuqur ichma-ich joylashish va sekin chizishga olib kelardi. RelativeLayout bu muammoni bir iyerarxiya darajasida nisbiy joylashtirishni taklif qilib hal qildi. Biroq, uning moslashuvchanligi zamonaviy ConstraintLayout bilan solishtirganda cheklangan: RelativeLayout zanjirlar, to'siqlar, yo'naltirgichlar va foiz o'lchamlarini qo'llab-quvvatlamaydi.
RelativeLayout ikkita asosiy xususiyatga ega: bitta onMeasure o'tishi (weight bilan LinearLayout dan farqli o'laroq, ikkita o'tishni talab qiladi) va e'lon qilish tartibiga bog'liqlik — agar A elementi B elementiga murojaat qilsa va B A dan keyin e'lon qilingan bo'lsa, B A ni o'lchash vaqtida ma'lum o'lchamga ega bo'lishi kerak. Android Developers Guide (2024) ma'lumotlariga ko'ra, RelativeLayout bir o'tishda o'lchaydi, agar barcha qoidalar allaqachon o'lchangan elementlarga murojaat qilsa. Aks holda, ikkinchi o'tish talab qilinadi, bu esa unumdorlikni pasaytiradi.
RelativeLayout nisbiy joylashtirish talab qilinadigan 3–7 elementli oddiy maketlar uchun oqlanadi (tugma ustidagi yozuv, matn o'ngidagi ikona, ekran pastidagi panel). Yangi loyihalar uchun ConstraintLayout tavsiya etiladi, lekin RelativeLayout hali ham eski kod va kutubxonalarda keng qo'llaniladi.
RelativeLayout ikki turdagi qoidalardan foydalanadi: relative-qoidalar (boshqa elementga nisbatan joylashtirish) va align-qoidalar (ota-onaga bog'lash). Har bir bolak element cheksiz miqdordagi qoidalarga ega bo'lishi mumkin, ammo ziddiyatli qoidalar (masalan, alignParentTop va boshqa elementning below) atributda oxirgi e'lon qilingan foydasiga hal qilinadi.
Relative-qoidalar:
- android:layout_above="@id/target" — elementning pastki chekkasi target ning yuqori chekkasiga bog'lanadi.
- android:layout_below="@id/target" — elementning yuqori chekkasi target ning pastki chekkasiga bog'lanadi.
- android:layout_toLeftOf="@id/target" — o'ng chekka target ning chap chekkasiga bog'lanadi.
- android:layout_toRightOf="@id/target" — chap chekka target ning o'ng chekkasiga bog'lanadi.
- android:layout_toStartOf="@id/target" — RTL lokalizatsiyalari uchun toLeftOf analogi.
- android:layout_toEndOf="@id/target" — RTL uchun toRightOf analogi.
Align-qoidalar (ota-onaga):
- android:layout_alignParentTop="true" — elementning yuqori chekkasi ota-onaning yuqori chekkasi bilan mos keladi.
- android:layout_alignParentBottom="true" — pastki chekka ota-onaning pastki chekkasi bilan mos keladi.
- android:layout_alignParentLeft="true" — chap chekka ota-onaning chap chekkasi bilan mos keladi.
- android:layout_alignParentRight="true" — o'ng chekka ota-onaning o'ng chekkasi bilan mos keladi.
- android:layout_alignParentStart va android:layout_alignParentEnd — RTL uchun.
Boshqa elementlarga align-qoidalar:
- android:layout_alignTop="@id/target" — elementning yuqori qismi target ning yuqori qismi bilan mos keladi.
- android:layout_alignBottom, android:layout_alignLeft, android:layout_alignRight, android:layout_alignStart, android:layout_alignEnd — xuddi shunday.
- android:layout_alignBaseline="@id/target" — matnning asosiy chizig'i bo'ylab tekislash (turli shrift o'lchamli qatorlar uchun foydali).
RelativeLayout da markazlashtirish uchta atribut bilan belgilanadi: android:layout_centerInParent="true" (ota-onaning ikkala o'qda markazi), android:layout_centerHorizontal="true" (gorizontal markaz) va android:layout_centerVertical="true" (vertikal markaz). Markazlashtirish boshqa qoidalar bilan mos keladi: element gorizontal markazlashtirilishi va bir vaqtning o'zida ota-onaning pastki chekkasiga bog'lanishi mumkin.
Ustma-ust tushish tartibi (Z-order) RelativeLayout da XML dagi elementlarning e'lon qilish tartibi bilan aniqlanadi. Birinchi e'lon qilingan element birinchi chiziladi (pastda bo'ladi), oxirgisi — oxirgi (yuqorida bo'ladi). XML ni o'zgartirmasdan ustma-ust tushish tartibini o'zgartirish kerak bo'lsa, android:elevation (API 21 dan boshlab) dan foydalaning — yuqori elevation ga ega elementlar ustidan chiziladi. API 21 dan past versiyalar uchun ustma-ust tushish tartibi faqat e'lon qilish tartibi bilan boshqariladi.
Muhim: RelativeLayout ota-ona uchun android:elevation atributini qo'llab-quvvatlamaydi — har bir element o'z elevation ini mustaqil boshqaradi. Joylashtirish qoidalari va elevation o'rtasida ziddiyat bo'lganda (masalan, bir-birining ustiga chiqadigan elementlar) elevation chizishda ustunlikka ega, lekin joylashtirishda emas — yuqori elevation ga ega element boshqasini vizual ravishda yopishi mumkin, hatto uning layout qoidalari uni «orqada» joylashtirsa ham.
Avatar yuqorida markazda, ism avatar ostida, holat ism ostida, harakat tugmasi ekran pastida. Barcha elementlar ketma-ket bog'lash uchun relative-qoidalardan foydalanadi.
<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="Ivan Ivanov"
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="Online"
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="Profilni tahrirlash" />
</RelativeLayout>
Avatar marginTop + centerHorizontal orqali yuqoriga bog'lanadi, ism — layout_below bilan avatar ostida, holat — ism ostida, tugma — alignParentBottom bilan ota-onaning pastki chekkasiga bog'lanadi. Barcha elementlar bir-biridan mustaqil, zanjir yoki ichma-ich joylashish yo'q.
Qizil nishon (raqamli doira) bilan ikona yuqori o'ng burchakda. Nishon ikonaga nisbatan uning chekkalariga align bilan bir-birining ustiga chiqish uchun manfiy margin lar bilan joylashtiriladi.
<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>
Nishon ikonaning yuqori va o'ng chekkasiga bog'lanadi. Manfiy margin lar (-6dp) nishonni tashqariga chiqarib, ikona chegarasining ustiga chiqish effektini yaratadi. Bu RelativeLayout bo'lmaganida FrameLayout yoki maxsus chizishni talab qiladigan mashhur bildirishnoma namunasidir.
Kirish formasi: logo yuqorida markazda, uning ostida elektron pochta maydoni, elektron pochta ostida parol maydoni, parol ostida «Kirish» tugmasi, «Ro'yxatdan o'tish» havolasi pastga bog'langan. Barcha elementlar layout_below orqali ketma-ket bog'langan.
<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="Parol"
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="Kirish" />
<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="Hisobingiz yo'qmi? Ro'yxatdan o'ting"
android:textColor="@color/primary" />
</RelativeLayout>
Ekran bir iyerarxiya darajasida 5 elementdan foydalanadi. Yuqoridan pastga oqim (logo → elektron pochta → parol → tugma) layout_below orqali ta'minlanadi, havola esa alignParentBottom bilan pastga bog'lanadi. Xuddi shu funksionallik uchun LinearLayout ikkita ichma-ich konteynerni talab qiladi (biri yuqori guruh uchun, ikkinchisi weight bilan havola uchun).
Nisbiy joylashtirish uchun ikki ViewGroup ni taqqoslash: RelativeLayout (klassik, API 1+) va ConstraintLayout (zamonaviy, Jetpack). Mezonlar: moslashuvchanlik, unumdorlik, RTL qo'llab-quvvatlash va adaptivlik.
| Xususiyat | RelativeLayout | ConstraintLayout |
|---|---|---|
| Foiz o'lchamlari | Yo'q (faqat qat'iy va match_parent) | Ha (width_percent, height_percent, guideline_percent) |
| RTL qo'llab-quvvatlash | start/end orqali (API 17+) | Ichki |
| Chain / zanjirlar | Yo'q | Ha (spread, spread_inside, packed) |
| Barrier / Group / Flow | Yo'q | Ha (virtual yordamchilar) |
| MotionLayout animatsiyalari | Yo'q | Ha |
| onMeasure o'tishlari | 1 (bog'liqlik davrlari bo'lmasa) | 2 (har doim, lekin optimallashtirilgan) |
| Markazlashtirish | centerInParent, centerHorizontal, centerVertical | bias (0.0–1.0) bilan qarama-qarshi constraint lar orqali |
| Qachon ishlatish | Eski kod, 3–7 elementli oddiy maketlar | Yangi loyihalar, murakkab ekranlar, adaptiv maketlar |
RelativeLayout deyarli barcha jihatlarda ConstraintLayout dan past, bittasi bundan mustasno: API 1 dan boshlab Android SDK ga kiritilgan va qo'shimcha bog'liqliklarni talab qilmaydi. Hali ham API 14 (Android 4.0) dan past minSdk ishlatadigan loyihalar uchun RelativeLayout nisbiy joylashtirishning yagona standart variantidir. Barcha boshqa holatlarda Google ConstraintLayout ni tavsiya qiladi.
Tez-tez beriladigan savollar
Eng ehtimoliy sabab — yetarli miqdordagi joylashtirish qoidalarining yo'qligi. RelativeLayout dagi har bir element kamida bitta gorizontal qoidaga (alignParentLeft, toRightOf, centerHorizontal) va bitta vertikal qoidaga (alignParentTop, below, centerVertical) ega bo'lishi kerak. Qoidalar bo'lmasa, element (0,0) pozitsiyasida bo'ladi va boshqa elementlar ostida yoki ekrandan tashqarida yashirinishi mumkin. Ikkinchi sabab — tsiklik bog'liqlik (A elementi B ga, B elementi A ga bog'langan), bu oldindan aytib bo'lmaydigan xatti-harakatga olib keladi.
android:layout_centerInParent="true" atributidan foydalaning. U elementni ikkala o'qda bir vaqtning o'zida markazlashtiradi. Faqat gorizontal kerak bo'lsa — android:layout_centerHorizontal="true", faqat vertikal — android:layout_centerVertical="true". Markazlashtirish margin bilan birga ishlaydi — element belgilangan masofaga markazdan siljitiladi.
Mumkin, lekin tavsiya etilmaydi. RelativeLayout tsiklik bog'liqliklar mavjud bo'lganda ikkita onMeasure o'tishini bajaradi, bu RecyclerView ro'yxatlarida ConstraintLayout dan 15–30% sekinroq. RecyclerView item maketlari uchun ConstraintLayout dan foydalaning — u minimal o'lchash vaqti bilan tekis iyerarxiyani ta'minlaydi. Agar RelativeLayout eski loyihada ishlatilayotgan bo'lsa, elementlar tsiklik bog'liqlik yaratmasligiga ishonch hosil qiling va Profile GPU Rendering orqali aylantirish FPS ni o'lchang.
android:layout_margin barcha tomonlardan bir vaqtning o'zida masofa qo'yadi. android:layout_marginTop — faqat yuqoridan. Aniqroq atribut ustunlik qiladi: agar ham layout_margin (16dp), ham layout_marginTop (8dp) o'rnatilgan bo'lsa, yuqori masofa 8dp bo'ladi. RelativeLayout da margin constraint ga nisbatan ishlaydi, qo'shni elementga nisbatan emas: layout_marginTop layout_below="@id/target" bilan — bu elementning yuqori chekkasidan target ning pastki chekkasigacha bo'lgan masofa.
Xulosa
Biz kalit topshirig'i bilan mobil ilovani ishlab chiqamiz
IT Sectr 2017-yildan beri startaplar va korxonalar uchun iOS va Android ilovalarini yaratadi. Biz sizga maslahat beramiz va eng yaxshi yechimni taklif qilamiz.