Ipinapaliwanag namin kung ano ang ConstraintLayout — isang flexible na sistema ng pagpoposisyon para sa Android na nagbibigay-daan sa pagbuo ng mga flat hierarchy ng view gamit ang mga constraint sa halip na nested na LinearLayout at RelativeLayout. Niresolba ng ConstraintLayout ang problema ng "nesting hell" (layout nesting hell), binabawasan ang lalim ng hierarchy sa isang antas at pinapabilis ang pag-render ng screen. Ang library ay bahagi ng Jetpack at available simula sa Android 2.3 (API 9) sa pamamagitan ng support-library. Ang mga pangunahing mekanismo ay inilarawan sa opisyal na dokumentasyon ng Android.
Mga Pangunahing Punto
ConstraintLayout — ay isang ViewGroup mula sa AndroidX ConstraintLayout library, na idinisenyo para sa paglikha ng flexible at mahusay na mga interface sa pamamagitan ng declarative constraints. Hindi tulad ng LinearLayout na nag-aayos ng mga elemento sa isang linya, o RelativeLayout na nagpoposisyon kaugnay ng mga kapitbahay, pinapayagan ng ConstraintLayout na i-angkla ang bawat elemento kaugnay ng anumang iba pang elemento at parent nang sabay-sabay.
Ang library ay inihayag sa Google I/O 2016 bilang solusyon para sa pagpapabilis ng pag-render ng mga kumplikadong screen. Ang pangunahing problemang niresolba ng ConstraintLayout ay ang nesting ng layout. Ang bawat nested na ViewGroup ay nagdaragdag ng hindi bababa sa dalawang measure pass at isang layout pass. Ang screen na may 4 na antas ng nesting ay nagsasagawa ng 8 measure pass; ang ConstraintLayout na may parehong functionality — 2 pass lamang. Ayon sa data ng Google (Android Performance Blog, 2017), ang pagpapalit ng tatlong nested na LinearLayout ng isang ConstraintLayout ay nagbabawas ng oras ng onMeasure ng 40%.
Ang kasalukuyang bersyon na ConstraintLayout 2.1.4 ay stable na gumagana sa Android 2.3+ (API 9) sa pamamagitan ng AndroidX. Sa bersyon 2.0, lumitaw ang circular positioning, Flow (awtomatikong paglipat ng mga elemento) at suporta sa MotionLayout. Ang ConstraintLayout ay kinakailangan para sa pag-unawa sa modernong pag-develop ng Android — ginagamit ito sa Jetpack Compose bilang pangunahing konsepto ng mga modifier, sa mga default na template ng Android Studio at sa Material Design 3.
Ang flat hierarchy ng ConstraintLayout ay nangangahulugan na ang lahat ng child View ay nasa parehong antas ng nesting. Sa halip na ilagay ang elemento A sa LinearLayout, at ang LinearLayout sa RelativeLayout, ang lahat ng elemento ay direktang naka-angkla sa parent na ConstraintLayout o sa isa't isa sa pamamagitan ng mga attribute. Nagbibigay ito ng: mas mababang konsumo ng memorya (bawat ViewGroup ay isang object sa Java heap), pagpapabilis ng layout pass (mas kaunting recursive na tawag), mas predictable na pag-uugali sa pagbabago ng laki ng screen.
Constraint — ay isang koneksyon sa pagitan ng gilid ng isang View (o gitna nito) at gilid ng ibang View o parent. Ang bawat View ay maaaring magkaroon ng hanggang 8 constraint: kaliwa, itaas, kanan, ibaba, start, end, baseline at gitna. Para sa pagpoposisyon, sapat na ang dalawang perpendicular constraint (halimbawa, itaas + kaliwa).
Format ng attribute: app:layout_constraint[Source]_to[Target]Of="[id]" — kung saan ang Source ay ang naka-angkla na gilid (Left, Right, Top, Bottom, Start, End, Baseline), ang Target ay ang gilid ng destinasyon. Halimbawa: app:layout_constraintTop_toBottomOf="@+id/header" ay nangangahulugang "ang itaas na hangganan ng kasalukuyang elemento ay naka-angkla sa ibabang hangganan ng elementong header". Para sa pag-angkla sa parent, ginagamit ang id na parent.
Bias (paglipat) — parameter na gumagana sa pagkakaroon ng magkasalungat na constraint (left + right o top + bottom). Halaga mula 0 hanggang 1: 0 — naka-dikit sa kaliwa/itaas na gilid, 0.5 — naka-center, 1 — sa kanan/ibaba na gilid. Mga attribute: layout_constraintHorizontal_bias (0.0–1.0) at layout_constraintVertical_bias. Ang margin ay itinatakda ng karaniwang android:layout_margin*, ngunit ang constraint at margin ay gumagana nang independyente: ang margin ay distansya mula sa constraint, hindi mula sa kalapit na View.
Mula sa ConstraintLayout 1.1+, available ang suporta para sa porsyento na laki sa pamamagitan ng layout_constraintWidth_percent at layout_constraintHeight_percent. Ang halagang 0.3 ay nangangahulugang 30% ng lapad/taas ng parent. Sa kombinasyon sa bias, pinapayagan nito ang paglikha ng adaptive layout nang walang programming.
Chain — ay isang grupo ng dalawa o higit pang View na konektado sa pamamagitan ng bidirectional constraint (A naka-angkla sa B, B sa A). Ang mga chain ay awtomatikong namamahagi ng espasyo sa pagitan ng mga elemento sa isa sa mga mode: spread (pantay-pantay, isinasaalang-alang ang margin), spread_inside (pantay-pantay, mga dulong elemento na walang espasyo mula sa mga gilid), packed (mga elemento na magkadikit na may shared bias). Ang mode ay itinatakda ng attribute na app:layout_constraintHorizontal_chainStyle o layout_constraintVertical_chainStyle.
Guideline — isang pantulong na View, hindi nakikita sa runtime, ngunit nagtatakda ng linya para sa pag-angkla. Ang Guideline ay maaaring pahalang o patayo, na nakaposisyon sa dp, porsyento (app:layout_constraintGuide_percent) o may distansya mula sa gilid (app:layout_constraintGuide_begin/end). Ang mga Guideline ay kailangang-kailangan para sa adaptive layout — halimbawa, para sa paghahati ng screen sa dalawang pantay na hati anuman ang laki ng device.
Ayon sa data ng Google I/O 2017, ang mga chain na may spread_inside ay 15–20% mas mahusay kaysa sa nested na LinearLayout na may weight, dahil iniiwasan nila ang dobleng measure pass na kinakailangan para sa pagkalkula ng weight.
Barrier — isang virtual na View na dynamic na inaayos ang posisyon nito batay sa laki ng grupo ng mga elemento. Hindi tulad ng Guideline na may nakapirming posisyon, ang Barrier ay "tinutulak" ng pinakamalawak na elemento ng grupo. Halimbawa, kung mayroon kang pamagat at paglalarawan na may hindi tiyak na haba, ang Barrier na naka-angkla sa kanang gilid ng pinakamalawak na teksto ay nagbibigay-daan sa paglalagay ng icon kaagad pagkatapos ng mga ito. Mga attribute: app:barrierDirection (left, right, top, bottom, start, end) at app:constraint_referenced_ids (listahan ng id na pinaghihiwalay ng kuwit).
Group — isang virtual na container na namamahala ng visibility ng maraming View nang sabay-sabay. Sa halip na tawagan ang setVisibility para sa bawat elemento nang hiwalay, sapat na baguhin ang visibility ng isang Group. Ang Group ay hindi nakakaapekto sa pagpoposisyon — visibility lamang. Flow — isang virtual na katulong para sa paglikha ng "fluidal" na layout: ang mga elemento ay awtomatikong lumilipat sa bagong row/column kapag walang sapat na espasyo, tulad ng teksto sa isang talata. Sinusuportahan ng Flow ang wrapMode: none, chain at aligned.
Ang mga tool na ito (Barrier, Group, Flow, Guideline) ay tinatawag na virtual na katulong dahil hindi sila View sa klasikong kahulugan — hindi sila sumasakop ng espasyo sa hierarchy at hindi nakikilahok sa focus o touch event. Ang kanilang layunin ay pasimplehin ang pagpapanatili ng mga kumplikadong layout nang hindi nagdaragdag ng nested na container.
Simpleng form sa pag-login na may email field, password at button. Lahat ng elemento ay naka-angkla sa parent, maliban sa button — ito ay nasa ilalim ng password field. Gumagamit ng flat hierarchy — lahat ng tatlong elemento sa parehong antas.
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/email_input"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:layout_marginTop="32dp"
android:layout_marginHorizontal="16dp" />
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/password_input"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintTop_toBottomOf="@+id/email_input"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:layout_marginTop="16dp"
android:layout_marginHorizontal="16dp" />
<Button
android:id="@+id/login_button"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintTop_toBottomOf="@+id/password_input"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:layout_marginTop="24dp"
android:layout_marginHorizontal="16dp"
android:text="Mag-login" />
</androidx.constraintlayout.widget.ConstraintLayout>
Ang lahat ng elemento ay may lapad na 0dp (match_constraint), ibig sabihin ay umaabot mula start hanggang end ng constraint na isinasaalang-alang ang horizontal margin. Ito ay katumbas ng match_parent na may espasyo, ngunit walang nesting.
Tatlong button, pantay-pantay na ipinamahagi nang pahalang na may espasyo mula sa mga gilid. Ang spread_inside chain ay naglalagay ng mga dulong button sa mga gilid at ang gitnang button ay naka-center sa pagitan nila.
<Button
android:id="@+id/btn_left"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toLeftOf="@+id/btn_center"
android:text="Kaliwa" />
<Button
android:id="@+id/btn_center"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintLeft_toRightOf="@+id/btn_left"
app:layout_constraintRight_toLeftOf="@+id/btn_right"
android:text="Gitna" />
<Button
android:id="@+id/btn_right"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintLeft_toRightOf="@+id/btn_center"
app:layout_constraintRight_toRightOf="parent"
android:text="Kanan" />
Ang chain ay awtomatikong nalilikha kapag ang mga elemento ay may bidirectional constraint. Ang spread_inside mode ay itinatakda sa anumang elemento ng chain sa pamamagitan ng app:layout_constraintHorizontal_chainStyle="spread_inside". Tinatanggal nito ang pangangailangang gumamit ng LinearLayout na may weightSum at layout_weight.
Paglikha ng dalawang pantay na column sa pamamagitan ng vertical na Guideline sa 50%. Ang kaliwang elemento ay naka-angkla sa kaliwang gilid ng parent at sa kanang gilid sa guideline; ang kanang elemento — sa kaliwang gilid sa guideline at sa kanang gilid ng parent.
<androidx.constraintlayout.widget.Guideline
android:id="@+id/gl_midpoint"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_percent="0.5" />
<TextView
android:id="@+id/left_card"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toLeftOf="@+id/gl_midpoint"
android:layout_margin="8dp"
android:background="@color/card_background" />
<TextView
android:id="@+id/right_card"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toRightOf="@+id/gl_midpoint"
app:layout_constraintRight_toRightOf="parent"
android:layout_margin="8dp"
android:background="@color/card_background" />
Ang Guideline na may porsyentong 0.5 ay awtomatikong umaangkop sa lapad ng screen. Sa tablet at telepono, ang ratio ng column ay nananatiling 50/50. Para sa kaliwa/kanan na nomenklatura, gamitin ang start/end attribute para sa RTL compatibility.
Talahanayan ng paghahambing ng tatlong pangunahing ViewGroup para sa pag-develop ng Android: ConstraintLayout, LinearLayout at RelativeLayout. Mga pamantayan: flexibility, performance, pagiging kumplikado ng code at mga lugar ng aplikasyon.
| Katangian | ConstraintLayout | LinearLayout | RelativeLayout |
|---|---|---|---|
| Nesting | Flat (isang antas) | Nangangailangan ng nesting para sa kumplikadong layout | Isang antas, ngunit limitadong flexibility |
| Performance ng measure | 2 pass (~40% mas mabilis) | 4+ pass na may weight | 2 pass |
| Porsyento na laki | Oo (guide_percent, width_percent) | Sa pamamagitan lamang ng weight/frame | Hindi |
| Suporta sa RTL | Built-in (start/end) | Built-in | Sa pamamagitan ng start/end (API 17+) |
| Barrier/Group/Flow | Oo (virtual na katulong) | Hindi | Hindi |
| MotionLayout animation | Oo | Hindi | Hindi |
| Kailan gagamitin | Lahat ng kumplikadong layout, screen na may >5 elemento | Simpleng one-way na listahan, row na may button | Simpleng relative layout (mula sa legacy code) |
Ayon sa Android Vitals (Google, 2025), ang mga app na gumagamit ng ConstraintLayout bilang pangunahing container ay nagpapakita ng average na 18% na mas kaunting jank frame sa pag-render ng mga kumplikadong screen kumpara sa mga app na may nested na LinearLayout. Sa IT Sectr lumipat kami sa ConstraintLayout bilang pamantayan para sa lahat ng XML layout noong 2018 — binawasan nito ang average na lalim ng hierarchy ng screen mula 4.2 hanggang 1.8 antas at pinabilis ang pag-develop ng mga bagong form ng 25%.
Mga Madalas Itanong
Ang match_parent sa ConstraintLayout ay gumagana tulad ng dati — iniunat ang View sa laki ng parent. Ang 0dp (match_constraint) ay nangangahulugan na ang laki ng View ay kinakalkula mula sa mga constraint: kung ang kaliwa at kanang constraint na may margin ay itinakda, ang lapad = parent — marginLeft — marginRight. Pagkakaiba sa pag-uugali: hindi pinapansin ng match_parent ang bias at maaaring lumampas sa mga hangganan sa panahon ng animation; tama na isinasaalang-alang ng match_constraint ang lahat ng limitasyon at inirerekomenda ng Google bilang pangunahing mode para sa ConstraintLayout.
Gumamit ng kombinasyon: porsyento na laki (layout_constraintWidth_percent) para sa mga elementong dapat sumakop sa bahagi ng screen; Guideline na may porsyento para sa paghahati ng screen sa mga zone; Barrier para sa pagpoposisyon kaugnay ng dynamic na content; Flow na may wrapMode para sa paglipat ng mga card sa bagong row. Alternatibong approach — paggamit ng SlidingPaneLayout kasama ng ConstraintLayout para sa master-detail interface sa mga tablet.
Hindi ginagamit ng Jetpack Compose ang ConstraintLayout bilang ViewGroup, ngunit nagbibigay ito ng Compose na bersyon ng ConstraintLayout (androidx.constraintlayout:constraintlayout-compose) na may parehong API sa Kotlin DSL: createRefFor(), constrainAs(), linkTo(), chain(), guideFrom(). Ito ay kapaki-pakinabang para sa mga kumplikadong layout na mas madaling ilarawan sa pamamagitan ng constraint kaysa sa Column/Row. Gayunpaman, sa Compose inirerekomenda na magsimula sa Column/Row/Box at lumipat sa ConstraintLayout lamang kapag kailangan ang kumplikadong relative positioning.
Sa Android Studio buksan ang Layout Inspector (Tools → Layout Inspector), piliin ang tumatakbong app at i-hover ang problematikong elemento. Makikita mo ang lahat ng constraint, margin, padding at bias sa isang three-dimensional na view. Para sa XML, gamitin ang Design panel sa layout editor — itinatampok nito ang mga conflict ng constraint sa dilaw at kawalan ng constraint sa pula. Sa code, suriin na ang bawat View ay may dalawang perpendicular constraint, kung hindi ang elemento ay mapupunta sa (0,0).
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