Ipinapaliwanag namin ang esensya ng RelativeLayout — ViewGroup sa Android SDK para sa pagpoposisyon ng mga child element na may kaugnayan sa isa't isa o may kaugnayan sa magulang na container. Hindi tulad ng LinearLayout, na nag-aayos ng mga elemento nang mahigpit na sunud-sunod, pinapayagan ng RelativeLayout na ilagay ang anumang elemento sa kaliwa, kanan, itaas, ibaba o gitna na may kaugnayan sa anumang iba pang elemento ayon sa ID nito. Ginagawa nitong maginhawa ang RelativeLayout para sa mga overlapping at kumplikadong layout nang walang nesting. Ang mga pangunahing panuntunan ay inilarawan sa dokumentasyon ng Android Developers.
Mga Pangunahing Punto
RelativeLayout — ViewGroup na lumitaw sa Android SDK mula noong API Level 1, na nagpoposisyon ng mga child element sa pamamagitan ng mga deklaratibong panuntunan (layout rules) na may kaugnayan sa magulang o iba pang child element. Ang bawat panuntunan ay tinutukoy ng isang XML attribute tulad ng android:layout_above, android:layout_below, android:layout_toLeftOf na may halaga ng ID ng target na elemento.
Bago ang pagdating ng RelativeLayout, napilitan ang mga developer na gumamit ng nested LinearLayout para sa bawat hindi karaniwang pagpoposisyon — ito ay humantong sa malalim na nesting at mabagal na pag-render. Nalutas ng RelativeLayout ang problemang ito sa pamamagitan ng pag-aalok ng relatibong pagpoposisyon sa isang antas ng hierarchy. Gayunpaman, limitado ang kakayahang umangkop nito kumpara sa modernong ConstraintLayout: Hindi sinusuportahan ng RelativeLayout ang mga chain, barrier, guide, at porsyentong laki.
Ang RelativeLayout ay may dalawang pangunahing katangian: isang onMeasure pass (hindi tulad ng LinearLayout na may weight na nangangailangan ng dalawang pass) at pag-asa sa pagkakasunud-sunod ng deklarasyon — kung ang elemento A ay tumutukoy sa elemento B at B ay idineklara pagkatapos ng A, ang B ay dapat may alam na laki sa oras ng pagsukat ng A. Ayon sa Android Developers Guide (2024), ginagawa ng RelativeLayout ang pagsukat sa isang pass kung ang lahat ng panuntunan ay tumutukoy sa nasukat nang mga elemento. Kung hindi, kinakailangan ang pangalawang pass, na nagpapababa ng pagganap.
Ang RelativeLayout ay makatwiran para sa mga simpleng layout na may 3–7 elemento kung saan kinakailangan ang relatibong pagpoposisyon (label sa itaas ng button, icon sa kanan ng teksto, panel sa ilalim ng screen). Para sa mga bagong proyekto, inirerekomenda ang ConstraintLayout, ngunit ang RelativeLayout ay malawak pa ring ginagamit sa legacy code at mga library.
Ang RelativeLayout ay gumagamit ng dalawang uri ng panuntunan: mga relative na panuntunan (pagpoposisyon na may kaugnayan sa ibang elemento) at mga align na panuntunan (pag-angkla sa magulang). Ang bawat child element ay maaaring magkaroon ng walang limitasyong bilang ng mga panuntunan, ngunit ang mga magkasalungat na panuntunan (hal. alignParentTop at below ng ibang elemento) ay nalulutas pabor sa huling idineklara sa attribute.
Relative na mga panuntunan:
- android:layout_above="@id/target" — ang ibabang gilid ng elemento ay naka-angkla sa itaas na gilid ng target.
- android:layout_below="@id/target" — ang itaas na gilid ng elemento ay naka-angkla sa ibabang gilid ng target.
- android:layout_toLeftOf="@id/target" — ang kanang gilid ay naka-angkla sa kaliwang gilid ng target.
- android:layout_toRightOf="@id/target" — ang kaliwang gilid ay naka-angkla sa kanang gilid ng target.
- android:layout_toStartOf="@id/target" — analog ng toLeftOf para sa mga RTL localization.
- android:layout_toEndOf="@id/target" — analog ng toRightOf para sa RTL.
Align na mga panuntunan (sa magulang):
- android:layout_alignParentTop="true" — ang itaas na gilid ng elemento ay tumutugma sa itaas na gilid ng magulang.
- android:layout_alignParentBottom="true" — ang ibabang gilid ay tumutugma sa ibabang gilid ng magulang.
- android:layout_alignParentLeft="true" — ang kaliwang gilid ay tumutugma sa kaliwang gilid ng magulang.
- android:layout_alignParentRight="true" — ang kanang gilid ay tumutugma sa kanang gilid ng magulang.
- android:layout_alignParentStart at android:layout_alignParentEnd — para sa RTL.
Align na mga panuntunan sa ibang elemento:
- android:layout_alignTop="@id/target" — ang itaas ng elemento ay tumutugma sa itaas ng target.
- android:layout_alignBottom, android:layout_alignLeft, android:layout_alignRight, android:layout_alignStart, android:layout_alignEnd — pareho.
- android:layout_alignBaseline="@id/target" — pagkakahanay sa baseline ng teksto (kapaki-pakinabang para sa mga row na may iba't ibang laki ng font).
Ang pagsentro sa RelativeLayout ay tinutukoy ng tatlong attribute: android:layout_centerInParent="true" (gitna ng magulang sa parehong axis), android:layout_centerHorizontal="true" (naka-sentro nang pahalang) at android:layout_centerVertical="true" (naka-sentro nang patayo). Ang pagsentro ay katugma sa iba pang mga panuntunan: ang isang elemento ay maaaring i-sentro nang pahalang at sabay na naka-angkla sa ibabang gilid ng magulang.
Ang pagkakasunud-sunod ng overlapping (Z-order) sa RelativeLayout ay tinutukoy ng pagkakasunud-sunod ng deklarasyon ng mga elemento sa XML. Ang unang idineklara na elemento ay unang iginuhit (nasa ibaba), ang huli — huli (nasa itaas). Kung kailangan mong baguhin ang pagkakasunud-sunod ng overlapping nang hindi binabago ang XML, gamitin ang android:elevation (simula sa API 21) — ang mga elementong may mas mataas na elevation ay iginuhit sa ibabaw. Para sa mga bersyong mas mababa sa API 21, ang pagkakasunud-sunod ng overlapping ay inaayos lamang sa pamamagitan ng pagkakasunud-sunod ng deklarasyon.
Mahalaga: Hindi sinusuportahan ng RelativeLayout ang attribute na android:elevation para sa magulang — bawat elemento ay namamahala ng sarili nitong elevation nang nakapag-iisa. Sa kaso ng salungatan sa pagitan ng mga panuntunan sa pagpoposisyon at elevation (hal. mga overlapping na elemento), ang elevation ay may priyoridad sa pagguhit, ngunit hindi sa pagpoposisyon — ang isang elemento na may mas mataas na elevation ay maaaring biswal na matakpan ang isa pa, kahit na ang mga layout panuntunan nito ay naglalagay nito sa likod.
Avatar sa gitna itaas, pangalan sa ilalim ng avatar, status sa ilalim ng pangalan, action button sa ilalim ng screen. Lahat ng elemento ay gumagamit ng relative na mga panuntunan para sa sunud-sunod na pag-angkla.
<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="I-edit ang profile" />
</RelativeLayout>
Ang avatar ay naka-angkla sa itaas sa pamamagitan ng marginTop + centerHorizontal, pangalan — sa ilalim ng avatar sa pamamagitan ng layout_below, status — sa ilalim ng pangalan, button — sa ibabang gilid ng magulang sa pamamagitan ng alignParentBottom. Lahat ng elemento ay independyente sa isa't isa, walang mga chain o nesting.
Icon na may pulang badge (bilog na may numero) sa kanang itaas na sulok. Ang badge ay naka-position na may kaugnayan sa icon sa pamamagitan ng align sa mga gilid nito na may negatibong margin para sa overlapping.
<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>
Ang badge ay naka-angkla sa itaas at kanang gilid ng icon. Ang mga negatibong margin (-6dp) ay naglilipat ng badge palabas, na lumilikha ng epekto ng paglampas sa hangganan ng icon. Ito ay isang sikat na pattern para sa mga notification na kung wala ang RelativeLayout ay mangangailangan ng FrameLayout o custom na pagguhit.
Login form: logo sa gitna itaas, field ng email sa ilalim nito, field ng password sa ilalim ng email, button na 'Mag-login' sa ilalim ng password, link na 'Magrehistro' na naka-pin sa ibaba. Lahat ng elemento ay sunud-sunod na naka-angkla sa pamamagitan ng layout_below.
<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="Password"
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="Mag-login" />
<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="Wala pang account? Magrehistro"
android:textColor="@color/primary" />
</RelativeLayout>
Gumagamit ang screen ng 5 elemento sa isang antas ng hierarchy. Ang daloy mula itaas hanggang ibaba (logo → email → password → button) ay ibinibigay ng layout_below, at ang link ay naka-pin sa ibaba sa pamamagitan ng alignParentBottom. Para sa parehong functionality, ang LinearLayout ay mangangailangan ng dalawang nested container (isa para sa itaas na grupo, ang pangalawa para sa link na may weight).
Paghahambing ng dalawang ViewGroup para sa relatibong pagpoposisyon: RelativeLayout (klasiko, API 1+) at ConstraintLayout (moderno, Jetpack). Mga pamantayan: kakayahang umangkop, pagganap, suporta sa RTL at kakayahang umangkop.
| Katangian | RelativeLayout | ConstraintLayout |
|---|---|---|
| Porsyentong laki | Hindi (fixed at match_parent lang) | Oo (width_percent, height_percent, guideline_percent) |
| Suporta sa RTL | Sa pamamagitan ng start/end (API 17+) | Built-in |
| Chain / mga kadena | Hindi | Oo (spread, spread_inside, packed) |
| Barrier / Group / Flow | Hindi | Oo (virtual na mga helper) |
| MotionLayout animation | Hindi | Oo |
| onMeasure passes | 1 (walang dependency cycles) | 2 (palagi, ngunit optimized) |
| Pagsentro | centerInParent, centerHorizontal, centerVertical | Sa pamamagitan ng bias (0.0–1.0) na may kabaligtaran na constraints |
| Kailan gagamitin | Legacy code, simpleng layout na may 3–7 elemento | Bagong proyekto, kumplikadong screen, adaptive na layout |
Ang RelativeLayout ay mas mababa sa ConstraintLayout sa halos lahat ng aspeto, maliban sa isa: ito ay naka-embed sa Android SDK mula noong API 1 at hindi nangangailangan ng mga karagdagang dependency. Para sa mga proyektong gumagamit pa rin ng minSdk na mas mababa sa API 14 (Android 4.0), ang RelativeLayout ay ang tanging standard na opsyon para sa relatibong pagpoposisyon. Sa lahat ng iba pang kaso, inirerekomenda ng Google ang ConstraintLayout.
Mga Madalas Itanong
Ang pinaka-malamang na dahilan — kakulangan ng sapat na bilang ng mga panuntunan sa pagpoposisyon. Ang bawat elemento sa RelativeLayout ay dapat magkaroon ng kahit isang pahalang na panuntunan (alignParentLeft, toRightOf, centerHorizontal) at isang patayong panuntunan (alignParentTop, below, centerVertical). Kung walang mga panuntunan, ang elemento ay mapupunta sa posisyon (0,0) at maaaring maitago sa ilalim ng iba pang mga elemento o sa labas ng screen. Ang pangalawang dahilan — isang cyclic dependency (elemento A ay naka-angkla sa B, B ay naka-angkla sa A), na humahantong sa hindi inaasahang pag-uugali.
Gamitin ang attribute na android:layout_centerInParent="true". Ito ay nagsi-sentro ng elemento sa parehong axis nang sabay-sabay. Kung kailangan lang pahalang — android:layout_centerHorizontal="true", patayo lang — android:layout_centerVertical="true". Gumagana ang pagsentro kasama ng margin — ang elemento ay ililipat kaugnay sa gitna ng tinukoy na distansya.
Maaari, ngunit hindi inirerekomenda. Ang RelativeLayout ay nagsasagawa ng dalawang onMeasure pass sa pagkakaroon ng cyclic dependencies, na 15–30% mas mabagal kaysa sa ConstraintLayout sa mga listahan ng RecyclerView. Para sa mga item layout ng RecyclerView, gamitin ang ConstraintLayout — nagbibigay ito ng flat hierarchy na may minimal na oras ng pagsukat. Kung ang RelativeLayout ay ginagamit na sa isang legacy na proyekto, siguraduhin na ang mga elemento ay hindi lumilikha ng cyclic dependencies at sukatin ang FPS ng pag-scroll sa pamamagitan ng Profile GPU Rendering.
android:layout_margin ay nagtatakda ng margin mula sa lahat ng panig nang sabay-sabay. android:layout_marginTop — mula sa itaas lamang. Ang mas tiyak na attribute ay may priyoridad: kung parehong nakatakda ang layout_margin (16dp) at layout_marginTop (8dp), ang itaas na margin ay magiging 8dp. Sa RelativeLayout, ang margin ay gumagana kaugnay sa constraint, hindi kaugnay sa katabing elemento: ang layout_marginTop na may layout_below="@id/target" — ito ang distansya mula sa itaas na gilid ng elemento hanggang sa ibabang gilid ng target.
Buod
Gagawa kami ng mobile application na turnkey
Gumagawa ang IT Sectr ng mga iOS at Android application para sa mga startup at negosyo mula noong 2017. Magpapayo kami sa iyo at magmumungkahi ng pinakamahusay na solusyon.
Basahin din