RelativeLayout — جوهر، قواعد التخطيط في تطبيقات Android

المؤلف: IT Sectr نُشر: 2026-02-24 وقت القراءة: 9 دق

نشرح جوهر RelativeLayout — ViewGroup في Android SDK لوضع العناصر الفرعية بالنسبة لبعضها البعض أو بالنسبة للحاوية الأصل. على عكس LinearLayout، الذي يرتب العناصر بتسلسل صارم، يسمح RelativeLayout بوضع أي عنصر إلى اليسار أو اليمين أو أعلى أو أسفل أو في المنتصف بالنسبة لأي عنصر آخر بواسطة معرفه (ID). هذا يجعل RelativeLayout مناسبًا للتخطيطات المتداخلة والمعقدة دون تداخل. القواعد الأساسية موصوفة في توثيق Android Developers.

النقاط الرئيسية

  • layout_below / layout_above — تثبيت عنصر أعلى أو أسفل العنصر المحدد بواسطة المعرف؛ سمات رئيسية لبناء تدفق.
  • 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 بقيمة معرف العنصر الهدف.

قبل ظهور RelativeLayout، كان المطورون مضطرين لاستخدام LinearLayout متداخلة لكل تموضع غير قياسي — مما أدى إلى تداخل عميق وعرض بطيء. حل RelativeLayout هذه المشكلة بتقديم تموضع نسبي على مستوى هرمي واحد. ومع ذلك، فإن مرونته محدودة مقارنة بـ ConstraintLayout الحديث: RelativeLayout لا يدعم السلاسل أو الحواجز أو الأدلة أو الأبعاد النسبية.

لـ RelativeLayout ميزتان رئيسيتان: تمريرة onMeasure واحدة (على عكس LinearLayout مع weight التي تتطلب تمريرتين) و الاعتماد على ترتيب التصريح — إذا كان العنصر A يشير إلى العنصر B، و B معلن بعد A، فيجب أن يكون لـ B حجم معروف وقت قياس A. وفقًا لدليل مطوري Android (2024)، ينفذ RelativeLayout القياس في تمريرة واحدة إذا كانت جميع القواعد تشير إلى عناصر تم قياسها بالفعل. وإلا، يلزم تمريرة ثانية، مما يقلل الأداء.

متى تحتاج RelativeLayout

RelativeLayout مبرر للتخطيطات البسيطة التي تحتوي على 3–7 عناصر حيث يتطلب التموضع النسبي (تسمية فوق زر، أيقونة يمين النص، لوحة في أسفل الشاشة). للمشاريع الجديدة، يُوصى باستخدام ConstraintLayout، لكن RelativeLayout لا يزال مستخدمًا على نطاق واسع في الكود القديم والمكتبات.

قواعد التموضع: relative و align

يستخدم RelativeLayout نوعين من القواعد: قواعد relative (التموضع نسبة لعنصر آخر) وقواعد align (التثبيت بالأصل). يمكن أن يكون لكل عنصر فرعي عدد غير محدود من القواعد، لكن القواعد المتعارضة (مثل alignParentTop وbelow لعنصر آخر) تُحل لصالح آخر سمة معلنة.

قواعد relative: - android:layout_above="@id/target" — الحافة السفلية للعنصر مثبتة بالحافة العلوية للهدف. - android:layout_below="@id/target" — الحافة العلوية للعنصر مثبتة بالحافة السفلية للهدف. - android:layout_toLeftOf="@id/target" — الحافة اليمنى مثبتة بالحافة اليسرى للهدف. - android:layout_toRightOf="@id/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" — أعلى العنصر يطابق أعلى الهدف. - android:layout_alignBottom، android:layout_alignLeft، android:layout_alignRight، android:layout_alignStart، android:layout_alignEnd — مماثل. - android:layout_alignBaseline="@id/target" — محاذاة بخط الأساس للنص (مفيد للنصوص بأحجام خط مختلفة).

التمركز والترتيب Z

التمركز في RelativeLayout يُحدد بثلاث سمات: android:layout_centerInParent="true" (مركز الأصل على كلا المحورين)، android:layout_centerHorizontal="true" (مركز أفقيًا) و android:layout_centerVertical="true" (مركز رأسيًا). التمركز متوافق مع القواعد الأخرى: يمكن أن يكون العنصر متمركزًا أفقيًا ومثبتًا بالحافة السفلية للأصل.

الترتيب Z (ترتيب التداخل) في RelativeLayout يُحدد بترتيب تصريح العناصر في XML. أول عنصر مصرح به يُرسم أولاً (سيكون أسفل)، وآخر عنصر — آخرًا (سيكون أعلى). إذا كنت بحاجة لتغيير ترتيب التداخل دون تغيير XML، استخدم android:elevation (بدءًا من API 21) — العناصر ذات elevation الأعلى تُرسم فوق. للإصدارات الأقل من API 21، يتحكم ترتيب التصريح فقط في ترتيب التداخل.

مهم: RelativeLayout لا يدعم السمة android:elevation للأصل — كل عنصر يتحكم في elevation الخاص به. عندما تتعارض قواعد التموضع مع elevation (مثل العناصر المتداخلة)، يكون elevation له الأولوية للعرض، لكن ليس للتموضع — عنصر ذو elevation أعلى يمكنه التداخل بصريًا مع آخر، حتى لو كانت قواعد تخطيطه تضعه "خلف".

أمثلة: تخطيطات 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: لوحة بأيقونة وشارة

أيقونة مع شارة حمراء (دائرة برقم) في الزاوية العلوية اليمنى. الشارة موضوعة بالنسبة للأيقونة عبر محاذاة لحوافها بهوامش سالبة للتداخل.

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>

الشارة مثبتة بالحواف العلوية واليمنى للأيقونة. الهوامش السالبة (-6dp) تحرك الشارة للخارج، مما يخلق تأثير تداخل مع حدود الأيقونة. هذا نمط شائع للإشعارات، والذي بدون RelativeLayout سيتطلب FrameLayout أو رسمًا مخصصًا.

مثال 3: شاشة تسجيل الدخول مع RelativeLayout

نموذج تسجيل الدخول: الشعار متمركز في الأعلى، حقل البريد الإلكتروني أسفله، حقل كلمة المرور أسفل البريد، زر "تسجيل الدخول" أسفل كلمة المرور، رابط "التسجيل" مثبت بالأسفل. جميع العناصر مثبتة تسلسليًا عبر 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 عناصر على مستوى هرمي واحد. التدفق من أعلى لأسفل (شعار → بريد → كلمة مرور → زر) يتم عبر layout_below، والرابط يُدفع للأسفل عبر alignParentBottom. لنفس الوظيفة، سيتطلب LinearLayout حاويتين متداخلتين (واحدة للمجموعة العلوية، وأخرى للرابط مع weight).

RelativeLayout مقابل 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". يعمل التوسيط مع الهوامش — سيتم إزاحة العنصر بالنسبة للمركز حسب الإزاحة المحددة.

هل يمكن استخدام RelativeLayout في RecyclerView؟

نعم، لكنه غير موصى به. ينفذ RelativeLayout تمريرتين onMeasure في حالة وجود تبعيات دائرية، وهو أبطأ بنسبة 15–30% من ConstraintLayout في قوائم RecyclerView. لتخطيطات عناصر 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، يعمل الهامش بالنسبة للقيد، وليس بالنسبة للعنصر المجاور: layout_marginTop مع layout_below="@id/target" هو الهامش من الحافة العلوية للعنصر إلى الحافة السفلية للهدف.

الخلاصة

  • RelativeLayout — ViewGroup لوضع العناصر بالنسبة لبعضها أو للأصل عبر قواعد تعريفية.
  • قواعد التثبيت — layout_below/above (رأسي)، layout_toLeftOf/toRightOf (أفقي)، alignParentTop/Bottom (للأصل).
  • التمركز — centerInParent (مركز)، centerHorizontal (على X)، centerVertical (على Y) لمحاذاة سريعة.
  • الترتيب Z — يُحدد بترتيب التصريح في XML؛ elevation (API 21+) يغير الترتيب Z أثناء العرض.
  • القيود — لا توجد أبعاد نسبية أو سلاسل أو حواجز؛ التبعيات الدائرية تسبب تمريرة onMeasure ثانية.
  • الأداء — تمريرة onMeasure واحدة بدون دورات، لكنه أدنى من ConstraintLayout في التخطيطات المعقدة.
  • التوصية — استخدمه في المشاريع القديمة؛ للشاشات الجديدة اختر ConstraintLayout.

سنقوم بتطوير تطبيق جوال جاهز

تقدم IT Sectr تطبيقات iOS وAndroid للشركات الناشئة والشركات منذ عام 2017. سوف نقدم لك النصح ونقترح أفضل حل.

مناقشة المشروع

اقرأ أيضًا