RelativeLayout — Android SDK-da uşaq elementləri bir-birinə və ya valideyn konteynerə nisbətən yerləşdirmək üçün ViewGroup. Elementləri ciddi ardıcıl düzən LinearLayout-dan fərqli olaraq, RelativeLayout istənilən elementi ID-sinə görə digər elementin solunda, sağında, yuxarısında, aşağısında və ya mərkəzində yerləşdirməyə imkan verir. Bu, RelativeLayout-u iç-içə düzülmədən üst-üstə düşən və mürəkkəb maketlər üçün əlverişli edir. Əsas qaydalar Android Developers sənədlərində təsvir edilmişdir.
Əsas məqamlar
RelativeLayout — API Level 1-dən etibarən Android SDK-da mövcud olan, uşaq elementlərini valideynə və ya digər uşaq elementlərinə nisbətən deklarativ qaydalar (layout rules) vasitəsilə yerləşdirən ViewGroup. Hər bir qayda android:layout_above, android:layout_below, android:layout_toLeftOf kimi XML atributu ilə hədəf elementin ID-si göstərilərək təyin edilir.
RelativeLayout meydana gəlməzdən əvvəl tərtibatçılar hər qeyri-standart yerləşdirmə üçün iç-içə LinearLayout istifadə etməli olurdular — bu, dərin iç-içə düzülməyə və yavaş çəkməyə səbəb olurdu. RelativeLayout bu problemi eyni iyerarxiya səviyyəsində nisbi yerləşdirmə təklif edərək həll etdi. Bununla belə, onun çevikliyi müasir ConstraintLayout ilə müqayisədə məhduddur: RelativeLayout zəncirləri, maneələri, istiqamətləndiriciləri və faiz ölçülərini dəstəkləmir.
RelativeLayout-un iki əsas xüsusiyyəti var: bir keçidli onMeasure (weight ilə LinearLayout-dan fərqli olaraq, iki keçid tələb edir) və elan sırasından asılılıq — əgər A elementi B elementinə istinad edirsə və B A-dan sonra elan edilibsə, B A-nın ölçülməsi anında məlum ölçüyə malik olmalıdır. Android Developers Guide (2024) məlumatına görə, RelativeLayout bir keçiddə ölçmə aparır, əgər bütün qaydalar artıq ölçülmüş elementlərə istinad edirsə. Əks halda, ikinci keçid tələb olunur ki, bu da məhsuldarlığı azaldır.
RelativeLayout, nisbi yerləşdirmə tələb olunan 3–7 elementli sadə maketlər üçün uyğundur (düymənin üstündə yazı, mətnin sağında ikona, ekranın altında panel). Yeni layihələr üçün ConstraintLayout tövsiyə olunur, lakin RelativeLayout hələ də legacy-kodda və kitabxanalarda geniş istifadə olunur.
RelativeLayout iki növ qaydadan istifadə edir: relative-qaydalar (başqa elementə nisbətən yerləşdirmə) və align-qaydalar (valideynə bağlama). Hər bir uşaq elementi limitsiz sayda qaydaya malik ola bilər, lakin ziddiyyətli qaydalar (məsələn, alignParentTop və başqa elementin below) atributda son elan edilənin xeyrinə həll edilir.
Relative-qaydalar:
- android:layout_above="@id/target" — elementin aşağı kənarı target-in yuxarı kənarına bağlanır.
- android:layout_below="@id/target" — elementin yuxarı kənarı target-in aşağı kənarına bağlanır.
- android:layout_toLeftOf="@id/target" — sağ kənar target-in sol kənarına bağlanır.
- android:layout_toRightOf="@id/target" — sol kənar target-in sağ kənarına bağlanır.
- android:layout_toStartOf="@id/target" — RTL lokalizasiyaları üçün toLeftOf-un analoqu.
- android:layout_toEndOf="@id/target" — RTL üçün toRightOf-un analoqu.
Align-qaydalar (valideynə):
- android:layout_alignParentTop="true" — elementin yuxarı kənarı valideynin yuxarı kənarı ilə üst-üstə düşür.
- android:layout_alignParentBottom="true" — aşağı kənar valideynin aşağı kənarı ilə üst-üstə düşür.
- android:layout_alignParentLeft="true" — sol kənar valideynin sol kənarı ilə üst-üstə düşür.
- android:layout_alignParentRight="true" — sağ kənar valideynin sağ kənarı ilə üst-üstə düşür.
- android:layout_alignParentStart və android:layout_alignParentEnd — RTL üçün.
Digər elementlərə align-qaydalar:
- android:layout_alignTop="@id/target" — elementin yuxarı hissəsi target-in yuxarısı ilə üst-üstə düşür.
- android:layout_alignBottom, android:layout_alignLeft, android:layout_alignRight, android:layout_alignStart, android:layout_alignEnd — eyni qaydada.
- android:layout_alignBaseline="@id/target" — mətnin əsas xətti ilə düzləşdirmə (müxtəlif şrift ölçüləri olan sətirlər üçün faydalıdır).
RelativeLayout-da mərkəzləşdirmə üç atributla təyin edilir: android:layout_centerInParent="true" (valideynin hər iki oxda mərkəzi), android:layout_centerHorizontal="true" (üfüqi mərkəz) və android:layout_centerVertical="true" (şaquli mərkəz). Mərkəzləşdirmə digər qaydalarla uyğundur: element üfüqi mərkəzləşdirilə və eyni zamanda valideynin aşağı kənarına bağlana bilər.
Üst-üstə düşmə sırası (Z-order) RelativeLayout-da XML-də elementlərin elan sırası ilə müəyyən edilir. Birinci elan edilən element birinci çəkilir (aşağıda olacaq), sonuncu — sonuncu (yuxarıda olacaq). XML-i dəyişmədən üst-üstə düşmə sırasını dəyişmək lazımdırsa, android:elevation (API 21-dən etibarən) istifadə edin — daha yüksək elevation olan elementlər üstdən çəkilir. API 21-dən aşağı versiyalar üçün üst-üstə düşmə sırası yalnız elan sırası ilə tənzimlənir.
Vacib: RelativeLayout valideyn üçün android:elevation atributunu dəstəkləmir — hər bir element öz elevation-unu müstəqil idarə edir. Yerləşdirmə qaydaları ilə elevation arasında ziddiyyət olduqda (məsələn, üst-üstə düşən elementlər) elevation çəkmə zamanı üstünlük təşkil edir, lakin yerləşdirmə zamanı yox — daha yüksək elevation olan element vizual olaraq digərini örtə bilər, hətta onun layout qaydaları onu «arxada» yerləşdirsə belə.
Avatar yuxarıda mərkəzdə, ad avatarın altında, status adın altında, hərəkət düyməsi ekranın altında. Bütün elementlər ardıcıl bağlama üçün relative-qaydalardan istifadə edir.
<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="İvan İvanov"
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="Profili redaktə et" />
</RelativeLayout>
Avatar marginTop + centerHorizontal vasitəsilə yuxarıya bağlanır, ad — layout_below ilə avatarın altında, status — adın altında, düymə — alignParentBottom ilə valideynin aşağı kənarına bağlanır. Bütün elementlər bir-birindən müstəqildir, zəncir və iç-içə düzülmə yoxdur.
Sağ yuxarı küncdə qırmızı nişan (rəqəmli dairə) olan ikona. Nişan ikonaya nisbətən onun kənarlarına align ilə üst-üstə düşmə üçün mənfi margin-lərlə yerləşdirilir.
<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>
Nişan ikonanın yuxarı və sağ kənarına bağlanır. Mənfi margin-lər (-6dp) nişanı kənara çıxararaq ikona sərhədinin üst-üstə düşməsi effekti yaradır. Bu, RelativeLayout olmadan FrameLayout və ya xüsusi çəkmə tələb edən məşhur bildiriş nümunəsidir.
Giriş forması: loqo yuxarıda mərkəzdə, onun altında e-poçt sahəsi, e-poçtun altında şifrə sahəsi, şifrənin altında «Daxil ol» düyməsi, «Qeydiyyat» linki aşağıya bağlanır. Bütün elementlər layout_below ilə ardıcıl bağlanır.
<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="Şifrə"
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="Daxil ol" />
<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="Hesabınız yoxdur? Qeydiyyatdan keçin"
android:textColor="@color/primary" />
</RelativeLayout>
Ekran eyni iyerarxiya səviyyəsində 5 elementdən istifadə edir. Yuxarıdan aşağıya axın (loqo → e-poçt → şifrə → düymə) layout_below ilə təmin edilir, link isə alignParentBottom ilə aşağıya bağlanır. Eyni funksionallıq üçün LinearLayout iki iç-içə konteyner tələb edərdi (biri yuxarı qrup üçün, ikincisi weight ilə link üçün).
Nisbi yerləşdirmə üçün iki ViewGroup-un müqayisəsi: RelativeLayout (klassik, API 1+) və ConstraintLayout (müasir, Jetpack). Meyarlar: çeviklik, məhsuldarlıq, RTL dəstəyi və adaptivlik.
| Xüsusiyyət | RelativeLayout | ConstraintLayout |
|---|---|---|
| Faiz ölçüləri | Xeyr (yalnız sabit və match_parent) | Bəli (width_percent, height_percent, guideline_percent) |
| RTL dəstəyi | start/end vasitəsilə (API 17+) | Daxili |
| Chain / zəncirlər | Xeyr | Bəli (spread, spread_inside, packed) |
| Barrier / Group / Flow | Xeyr | Bəli (virtual köməkçilər) |
| MotionLayout animasiyaları | Xeyr | Bəli |
| onMeasure keçidləri | 1 (asılılıq dövrləri olmadan) | 2 (həmişə, lakin optimallaşdırılmış) |
| Mərkəzləşdirmə | centerInParent, centerHorizontal, centerVertical | bias (0.0–1.0) ilə əks constraint-lər vasitəsilə |
| Nə vaxt istifadə etməli | Legacy-kod, 3–7 elementli sadə maketlər | Yeni layihələr, mürəkkəb ekranlar, adaptiv maketlər |
RelativeLayout demək olar ki, hər aspektdə ConstraintLayout-dan geri qalır, biri istisna olmaqla: API 1-dən etibarən Android SDK-ya daxildir və əlavə asılılıq tələb etmir. Hələ də API 14-dən (Android 4.0) aşağı minSdk istifadə edən layihələr üçün RelativeLayout nisbi yerləşdirmənin yeganə standart variantıdır. Bütün digər hallarda Google ConstraintLayout tövsiyə edir.
Tez-tez verilən suallar
Ən ehtimal olunan səbəb — kifayət qədər yerləşdirmə qaydasının olmaması. RelativeLayout-dakı hər bir element ən azı bir üfüqi qaydaya (alignParentLeft, toRightOf, centerHorizontal) və bir şaquli qaydaya (alignParentTop, below, centerVertical) malik olmalıdır. Qaydalar yoxdursa, element (0,0) mövqeyində olur və digər elementlərin altında və ya ekrandan kənarda gizlənə bilər. İkinci səbəb — tsiklik asılılıq (A elementi B-yə, B elementi A-ya bağlanır), bu da gözlənilməz davranışa səbəb olur.
android:layout_centerInParent="true" atributundan istifadə edin. O, elementi hər iki oxda eyni anda mərkəzləşdirir. Yalnız üfüqi lazımdırsa — android:layout_centerHorizontal="true", yalnız şaquli — android:layout_centerVertical="true". Mərkəzləşdirmə margin ilə birlikdə işləyir — element göstərilən boşluq qədər mərkəzdən sürüşdürüləcək.
İstifadə etmək olar, amma tövsiyə edilmir. RelativeLayout tsiklik asılılıqlar olduqda iki onMeasure keçidi yerinə yetirir ki, bu da RecyclerView siyahılarında ConstraintLayout-dan 15–30% yavaşdır. RecyclerView item maketləri üçün ConstraintLayout istifadə edin — o, minimal ölçmə vaxtı ilə yastı iyerarxiya təmin edir. Legacy-layihədə RelativeLayout artıq istifadə olunursa, elementlərin tsiklik asılılıq yaratmadığından əmin olun və Profile GPU Rendering vasitəsilə sürüşdürmə FPS-ni ölçün.
android:layout_margin bütün tərəflərdən eyni anda boşluq qoyur. android:layout_marginTop — yalnız yuxarıdan. Daha spesifik atribut üstünlük təşkil edir: həm layout_margin (16dp), həm də layout_marginTop (8dp) təyin edilibsə, yuxarı boşluq 8dp olacaq. RelativeLayout-da margin constraint-ə nisbətən işləyir, qonşu elementə nisbətən deyil: layout_marginTop layout_below="@id/target" ilə — bu, elementin yuxarı kənarından target-in aşağı kənarına qədər olan boşluqdur.
Nəticə
Açar təslim mobil tətbiq hazırlayacağıq
IT Sectr 2017-ci ildən startaplar və bizneslər üçün iOS və Android tətbiqləri yaradır. Sizə məsləhət verəcəyik və ən yaxşı həlli təklif edəcəyik.
Həm də oxuyun