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 — اتصال لبه عنصر به لبه متناظر والد؛ برای هر چهار طرف کار می‌کند.
  • Center و مرکزچینی — centerInParent (مرکز هر دو محور)، centerHorizontal (مرکز در X)، centerVertical (مرکز در Y).
  • toLeftOf / toRightOf — قرار دادن عنصر در چپ یا راست عنصر مشخص شده، بدون هم‌پوشانی.
  • قواعد هم‌پوشانی — اگر قواعد متناقض باشند (مثلاً alignParentTop و below دیگری)، اولویت با آخرین قاعده اعلام شده در XML است.

RelativeLayout چیست؟

RelativeLayout — ViewGroup که از API Level 1 در Android SDK وجود دارد و عناصر فرزند را از طریق قواعد اعلامی (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 برای طرح‌های ساده با ۳–۷ عنصر که نیاز به موقعیت‌یابی نسبی دارند (برچسب بالای دکمه، آیکون سمت راست متن، پنل پایین صفحه) مناسب است. برای پروژه‌های جدید 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

مثال ۱: پروفایل کاربر

آواتار در مرکز بالا، نام زیر آواتار، وضعیت زیر نام، دکمه اقدام در پایین صفحه. همه عناصر از قواعد 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. همه عناصر مستقل از یکدیگر هستند، زنجیره یا تودرتو وجود ندارد.

مثال ۲: پنل با آیکون و نشان

آیکون با نشان قرمز (دایره با عدد) در گوشه بالا سمت راست. نشان نسبت به آیکون از طریق 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 منفی (۶- dp) نشان را به بیرون می‌کشاند و اثر هم‌پوشانی لبه آیکون را ایجاد می‌کند. این یک الگوی محبوب برای اعلان‌ها است که بدون RelativeLayout به FrameLayout یا رسم سفارشی نیاز داشت.

مثال ۳: صفحه ورود با 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>

صفحه از ۵ عنصر در یک سطح از سلسله‌مراتب استفاده می‌کند. جریان از بالا به پایین (لوگو → ایمیل → رمز → دکمه) از طریق 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خیربله
پیمایش‌های onMeasure۱ (بدون چرخه وابستگی)۲ (همیشه، اما بهینه‌شده)
مرکزچینیcenterInParent، centerHorizontal، centerVerticalاز طریق bias (۰.۰–۱.۰) با محدودیت‌های مخالف
زمان استفادهکد قدیمی، طرح‌های ساده با ۳–۷ عنصرپروژه‌های جدید، صفحه‌های پیچیده، طرح‌های تطبیقی

RelativeLayout تقریباً از همه نظر از ConstraintLayout پایین‌تر است، به جز یک مورد: از API 1 در Android SDK تعبیه شده است و به وابستگی اضافی نیاز ندارد. برای پروژه‌هایی که هنوز از minSdk پایین‌تر از API 14 (Android 4.0) استفاده می‌کنند، RelativeLayout تنها گزینه استاندارد برای موقعیت‌یابی نسبی است. در تمام موارد دیگر، Google ConstraintLayout را توصیه می‌کند.

سوالات متداول

چرا عنصر RelativeLayout نمایش داده نمی‌شود؟

محتمل‌ترین دلیل — نبود تعداد کافی قواعد موقعیت‌یابی. هر عنصر در RelativeLayout باید حداقل یک قاعده افقی (alignParentLeft، toRightOf، centerHorizontal) و یک قاعده عمودی (alignParentTop، below، centerVertical) داشته باشد. اگر قاعده‌ای نباشد، عنصر در موقعیت (۰,۰) قرار می‌گیرد و ممکن است زیر عناصر دیگر یا خارج از صفحه پنهان شود. دلیل دوم — وابستگی چرخه‌ای (عنصر A به B متصل است، B به A متصل است) که منجر به رفتار غیرقابل پیش‌بینی می‌شود.

چگونه یک عنصر را در مرکز صفحه در RelativeLayout قرار دهیم؟

از ویژگی android:layout_centerInParent="true" استفاده کنید. این عنصر را در هر دو محور هم‌زمان مرکزچین می‌کند. اگر فقط افقی نیاز دارید — android:layout_centerHorizontal="true"، فقط عمودی — android:layout_centerVertical="true". مرکزچینی همراه با margin کار می‌کند — عنصر به اندازه حاشیه مشخص شده از مرکز جابه‌جا می‌شود.

آیا می‌توان از RelativeLayout در RecyclerView استفاده کرد؟

می‌توان، اما توصیه نمی‌شود. RelativeLayout در صورت وجود وابستگی‌های چرخه‌ای دو پیمایش onMeasure انجام می‌دهد که در لیست‌های RecyclerView ۱۵–۳۰٪ کندتر از ConstraintLayout است. برای طرح‌های آیتم RecyclerView از ConstraintLayout استفاده کنید — این سلسله‌مراتب تخت با حداقل زمان اندازه‌گیری فراهم می‌کند. اگر RelativeLayout در پروژه قدیمی استفاده شده است، مطمئن شوید عناصر وابستگی چرخه‌ای ایجاد نمی‌کنند و FPS اسکرول را از طریق Profile GPU Rendering اندازه‌گیری کنید.

تفاوت layout_margin با layout_marginTop در RelativeLayout چیست؟

android:layout_margin حاشیه را از همه طرف هم‌زمان تعیین می‌کند. android:layout_marginTop — فقط از بالا. ویژگی خاص‌تر اولویت دارد: اگر هم layout_margin (۱۶dp) و هم layout_marginTop (۸dp) تنظیم شده باشند، حاشیه بالایی ۸dp خواهد بود. در RelativeLayout، margin نسبت به محدودیت (constraint) کار می‌کند، نه نسبت به عنصر مجاور: 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 می‌شود.
  • عملکرد — ۱ پیمایش onMeasure بدون چرخه، اما در طرح‌های پیچیده از ConstraintLayout پایین‌تر است.
  • توصیه — در پروژه‌های قدیمی استفاده کنید؛ برای صفحه‌های جدید ConstraintLayout را انتخاب کنید.

ما یک اپلیکیشن موبایل به صورت کلید در دست توسعه خواهیم داد

IT Sectr از سال 2017 برنامه‌های iOS و Android را برای استارتاپ‌ها و کسب‌وکارها ایجاد می‌کند. ما به شما مشاوره می‌دهیم و بهترین راه‌حل را پیشنهاد خواهیم کرد.

بحث درباره پروژه

همچنین بخوانید