FrameLayout: mahahalagang konsepto, simpleng pagpoposisyon sa Android

May-akda: IT Sectr Nai-publish: 2026-02-24 Oras ng pagbabasa: 8 min

Alamin ang mahahalagang konsepto ng FrameLayout — ang pinakasimpleng ViewGroup sa Android SDK, na idinisenyo para sa paglalagay ng isang elemento ng anak (karaniwan) o pagpapatong ng maraming elemento sa isa't isa. Ang FrameLayout ay kapaki-pakinabang para sa mga lalagyan ng placeholder, mga fragment, mga indicator ng pag-load, at mga elemento ng foreground. Hindi nito pinamamahalaan ang posisyon ng mga anak — bawat susunod na elemento ay iginuhit sa ibabaw ng nauna, at ang kanilang posisyon ay tinutukoy ng layout_gravity (left, top, right, bottom, center). Ang mga pangunahing sitwasyon ay inilarawan sa FrameLayout API Reference.

Mga pangunahing punto

  • Pagpapatong ng mga layer — inilalagay ng FrameLayout ang mga elemento nang sunud-sunod sa ibabaw ng bawat isa; ang huling idineklara sa XML ay iginuhit sa itaas ng lahat.
  • Foreground — ang atributong android:foreground ay nagpapahintulot sa paglalagay ng drawable sa ibabaw ng lahat ng elemento ng anak, kapaki-pakinabang para sa mga epekto at pag-mask.
  • measureAllChildren — bilang default, sinusukat ng FrameLayout ang lahat ng anak, kahit ang hindi nakikita (GONE). Ang pag-disable ay nagpapabilis ng rendering ng 20–60%.
  • layout_gravity — ang tanging paraan ng pagpoposisyon ng elemento ng anak sa loob ng FrameLayout: top, bottom, left, right, center.
  • Paggamit sa Fragment — ang FrameLayout ay karaniwang lalagyan para sa FragmentTransaction.replace(), na pumapalit sa nilalaman nang hindi muling ginagawa ang aktibidad.

Ano ang FrameLayout?

FrameLayout ay ang pinakasimpleng ViewGroup sa Android SDK, na idinisenyo para sa pag-block ng lugar ng screen at pagpapakita ng isang view ng anak (o pagpapatong ng marami). Hindi tulad ng LinearLayout (sunud-sunod na paglalagay) at RelativeLayout (kaugnay na pagpoposisyon), hindi binabago ng FrameLayout ang posisyon ng mga anak — bawat bagong child ay inilalagay bilang default sa kaliwang sulok sa itaas (0,0) at iginuhit sa ibabaw ng nauna.

Ang FrameLayout ay lumitaw sa API Level 1 at nananatiling pinakamagaan na lalagyan ng Android: hindi nito na-override ang onMeasure ng kumplikadong lohika at gumaganap ng pinakamababang bilang ng mga operasyon ng layout. Ayon sa Android Performance Blog, ginagawa ng FrameLayout ang onLayout sa isang pass at halos hindi nagdaragdag ng overhead kumpara sa direktang paglalagay ng View. Ginagawa nitong perpektong pagpipilian para sa mga lalagyan kung saan mahalaga ang bilis: mga layout ng item ng RecyclerView (kasama ang ConstraintLayout para sa pagpoposisyon), mga lalagyan ng fragment, mga layer ng overlay.

Ang default na laki ng FrameLayout ay tinutukoy ng pinakamalaking elemento ng anak (kung hindi nakatakda ang match_parent). Kung walang tinukoy na child, ang FrameLayout ay lumiliit sa (0,0). Ang atributong android:measureAllChildren (seksyon sa ibaba) ay nagbabago sa pag-uugaling ito.

FrameLayout sa hierarchy ng Android ViewGroup

Ang FrameLayout ay nagmamana mula sa ViewGroup at direktang magulang ng maraming espesyal na lalagyan: FragmentContainerView (mga fragment), CardView (mga card na may anino), ScrollView (na may isang child), NestedScrollView. Kapag gumagawa ng Activity na may Fragment navigation, ang karaniwang template ng Android Studio ay gumagamit ng FrameLayout (o FragmentContainerView) bilang pangunahing lalagyan para sa mga fragment.

Foreground at measureAllChildren

android:foreground — atributo ng FrameLayout na tumutukoy sa drawable na iginuhit sa ibabaw ng lahat ng elemento ng anak. Hindi tulad ng background (sa ilalim ng mga anak), ang foreground ay ipinapakita sa itaas ng nilalaman at maaaring maging transparent. Ginagamit para sa: mga epekto ng overlay sa pagpindot (ripple sa pamamagitan ng ?attr/selectableItemBackground), pag-mask ng mga larawan, pagpapakita ng mga indicator ng katayuan (checkmark ng pagpili sa ibabaw ng larawan).

Sinusuportahan ng foreground ang mga karaniwang mapagkukunan ng drawable: ColorDrawable, ShapeDrawable, RippleDrawable, LayerDrawable. Mula sa API 23+, ang android:foregroundGravity ay magagamit para sa pagpoposisyon ng foreground (fill, center, top, bottom). Sa mode na "puno" (fill), ang foreground ay nakaunat sa buong FrameLayout; sa mode na center — iginuhit sa gitna.

android:measureAllChildren — boolean na atributo (default true) na tumutukoy kung ang lahat ng elemento ng anak ay kailangang sukatin kapag kinakalkula ang laki ng FrameLayout. Kung true (default), isinasaalang-alang ng FrameLayout ang laki ng lahat ng anak, kabilang ang GONE (na may sukat na 0). Kung false, sinusukat lamang ng FrameLayout ang VISIBLE at INVISIBLE na mga anak — ang mga elementong GONE ay hindi kasama sa pagkalkula. Ayon sa Google I/O 2019, ang pag-disable ng measureAllChildren para sa mga lalagyan na may maraming elementong GONE (halimbawa, mga listahan na may pagpapalit ng visibility) ay nagpapabilis ng paunang rendering ng 20–60%.

layout_gravity: pagpoposisyon sa loob ng FrameLayout

android:layout_gravity — atributo ng elemento ng anak ng FrameLayout (at iba pang ViewGroup) na tumutukoy sa posisyon nito sa loob ng lalagyan. Sa FrameLayout, ang layout_gravity ay ang tanging paraan upang kontrolin ang posisyon ng elemento ng anak, dahil ang FrameLayout ay hindi nagbibigay ng sarili nitong mga panuntunan sa pagpoposisyon (tulad ng RelativeLayout) o direksyon (tulad ng LinearLayout).

Mga posibleng halaga: top, bottom, left, right, center, center_horizontal, center_vertical, fill, fill_horizontal, fill_vertical, clip_horizontal, clip_vertical. Pinagsasama sa pamamagitan ng |: android:layout_gravity="bottom|center_horizontal" — ang elemento ay idinikit sa ibabang gilid at naka-center nang pahalang. Para sa mga elemento na ang laki ay mas maliit kaysa sa FrameLayout, tinutukoy ng layout_gravity ang kanilang posisyon sa libreng espasyo.

Kung hindi nakatakda ang layout_gravity, bilang default ang elemento ay inilalagay sa kaliwang sulok sa itaas (top|left). Para sa FrameLayout na naglalaman ng maraming anak, ang bawat isa ay maaaring magkaroon ng sariling layout_gravity — isang elemento ay maaaring nasa kaliwang sulok sa itaas, isa pa sa kanang sulok sa ibaba, ang pangatlo sa gitna. Pinapayagan nito ang paglikha ng mga simpleng overlay (halimbawa, isang pangsarang ekis sa ibabaw ng larawan).

Pagkakaiba ng gravity vs layout_gravity

android:gravity (atributo ng magulang) ay nag-aayos ng nilalaman sa loob ng FrameLayout — halimbawa, teksto sa loob ng TextView. android:layout_gravity (atributo ng anak) ay nag-aayos ng elemento mismo sa loob ng FrameLayout. Sa konteksto ng FrameLayout, tinutukoy ng gravity kung paano inaayos ang mga anak bilang default (katulad ng layout_gravity para sa lahat ng anak nang sabay), ngunit ang layout_gravity ng bawat partikular na elemento ay nag-o-override sa halaga ng magulang.

Mga halimbawa: XML at mga kaso ng paggamit

Halimbawa 1: Pangunahing pagpapatong — label sa larawan

Larawan at text label sa kanang sulok sa ibaba. Ang FrameLayout ay naglalaman ng ImageView sa buong screen at TextView na may layout_gravity="bottom|end" para sa pagpoposisyon sa ibabaw.

xml
<FrameLayout
    android:layout_width="match_parent"
    android:layout_height="200dp">

    <ImageView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:src="@drawable/product_photo"
        android:scaleType="centerCrop" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom|end"
        android:layout_margin="8dp"
        android:background="@drawable/badge_background"
        android:elevation="2dp"
        android:paddingHorizontal="8dp"
        android:paddingVertical="4dp"
        android:text="-30%"
        android:textColor="@android:color/white"
        android:textSize="14sp"
        android:textStyle="bold" />

</FrameLayout>

Sinasakop ng ImageView ang buong FrameLayout (200dp taas). Ang TextView na may layout_gravity="bottom|end" ay inilalagay sa kanang sulok sa ibaba sa ibabaw ng larawan. Ang elevation=2dp ay nagdaragdag ng anino sa ilalim ng label, na naghihiwalay nito nang biswal mula sa larawan. Ito ay isang minimal na halimbawa na sa LinearLayout ay mangangailangan ng nested na lalagyan o custom na code.

Halimbawa 2: Indicator ng pag-load (progress bar sa ibabaw ng nilalaman)

Screen na may nilalaman at progress bar sa gitna na lumilitaw habang naglo-load. Ang FrameLayout ay naglalaman ng dalawang elemento: ang nilalaman at ProgressBar na may visibility="gone" (pinalitan sa code).

xml
<FrameLayout
    android:id="@+id/content_container"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:id="@+id/content_text"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center"
        android:text="Nilalaman na na-load"
        android:textSize="18sp" />

    <ProgressBar
        android:id="@+id/loading_spinner"
        android:layout_width="48dp"
        android:layout_height="48dp"
        android:layout_gravity="center"
        android:visibility="gone" />

</FrameLayout>

Ang ProgressBar ay nakatago bilang default (gone). Sa pagsisimula ng pag-load, sa code ay tinatawag ang findViewById(R.id.loading_spinner).visibility = View.VISIBLE — lumilitaw ang spinner sa gitna sa ibabaw ng nilalaman. Pagkatapos ng pag-load — .visibility = View.GONE. Tinitiyak ng FrameLayout ang pagpapatong nang hindi binabago ang posisyon ng nilalaman — hindi gumagalaw ang teksto kapag lumitaw ang spinner, dahil ang ProgressBar ay iginuhit sa ibabaw.

Halimbawa 3: Lalagyan ng fragment

FrameLayout bilang karaniwang lalagyan para sa FragmentTransaction. Pinapalitan ng aktibidad ang mga fragment sa loob ng lalagyang ito depende sa nabigasyon.

xml
<FrameLayout
    android:id="@+id/fragment_container"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />
kotlin
import androidx.fragment.app.FragmentTransaction

val fragmentContainer = R.id.fragment_container

fun navigateTo(fragment: Fragment) {
    supportFragmentManager
        .beginTransaction()
        .setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE)
        .replace(fragmentContainer, fragment)
        .addToBackStack(null)
        .commit()
}

FrameLayout bilang lalagyan ng fragment — ang pinakamagaan na paraan upang suportahan ang Fragment Navigation. Ang FragmentContainerView (tagapagmana ng FrameLayout) ay inirerekomenda sa Navigation Component 2.4+, ngunit ang simpleng FrameLayout ay nananatiling wasto para sa manu-manong FragmentTransaction. Ang pangunahing bentahe — ang FragmentTransaction.replace() ay ganap na pumapalit sa nilalaman nang hindi naaapektuhan ang Activity.

Kailan gagamitin ang FrameLayout

Ang FrameLayout ay optimal para sa apat na sitwasyon: lalagyan ng fragment (FragmentContainerView o FrameLayout), overlay ng pag-load (ProgressBar sa ibabaw ng nilalaman), mga label ng card (marka sa larawan), lalagyan ng placeholder para sa ViewStub (tamad na pag-load).

Hindi angkop para sa: kumplikadong pagpoposisyon ng maraming elemento (gamitin ang ConstraintLayout), sunud-sunod na listahan (LinearLayout o RecyclerView), mga dynamic na layout na may pagbabago ng pagkakasunud-sunod ng mga elemento.

FrameLayout bilang root na elemento ng screen — masamang kasanayan kung ang screen ay naglalaman ng higit sa 2–3 elemento. Para sa root na lalagyan, gamitin ang ConstraintLayout — nagbibigay ito ng higit na kontrol sa pagpoposisyon nang walang pagkawala ng pagganap. Gamitin lamang ang FrameLayout para sa mga bloke ng anak kung saan kailangan ang pagpapatong o placeholder.

Mga madalas itanong

Ano ang pagkakaiba sa pagitan ng FrameLayout at ConstraintLayout?

FrameLayout — isang minimalistang lalagyan na walang sistema ng pagpoposisyon (layout_gravity lamang), na idinisenyo para sa pagpapatong ng mga elemento. ConstraintLayout — isang kumpletong sistema ng layout na may mga constraint, kadena, hadlang, porsyentong laki, at suporta sa MotionLayout. Ang FrameLayout ay mas mabilis para sa mga simpleng kaso (1 child o overlay); ang ConstraintLayout ay kinakailangan para sa mga kumplikadong layout. Pagpipilian: FrameLayout para sa overlay ng pag-load at lalagyan ng fragment; ConstraintLayout para sa lahat ng iba pa.

Paano gagawin na ang FrameLayout ay sumasakop lamang sa puwang ng pinakamalaking child?

Itakda ang laki ng FrameLayout sa wrap_content sa nais na axis (android:layout_width="wrap_content" at/o android:layout_height="wrap_content"). Sa kasong ito, ang FrameLayout ay aangkop sa laki ng pinakamalaking elemento ng anak. Kung ang lahat ng anak ay mas maliit kaysa sa FrameLayout, ang sobrang espasyo ay mananatiling walang laman. Para sa tumpak na kontrol, gamitin ang match_parent na may nakapirming padding.

Bakit nagkakapatong ang mga elemento sa FrameLayout?

Ito ay normal na pag-uugali ng FrameLayout — hindi nito ipinamahagi ang mga anak sa espasyo, kundi iginuguhit ang mga ito nang sunud-sunod sa ibabaw ng bawat isa. Kung nais mong hindi magkapatong ang mga elemento, gumamit ng ibang lalagyan (LinearLayout, ConstraintLayout). Para sa bahagyang pagkakapatong na may kontrol sa pagkakasunud-sunod ng pagguhit, gamitin ang layout_gravity para sa paglipat at elevation para sa Z-order.

Alin ang mas mabilis: FrameLayout o ConstraintLayout?

Ang FrameLayout ay mas mabilis para sa napakasimpleng mga kaso — isang elemento ng anak, nang walang kumplikadong pagpoposisyon. Ginagawa ng FrameLayout ang onMeasure sa pinakamababang oras, nang hindi kinakalkula ang mga constraint. Gayunpaman, ang pagkakaiba ay kapansin-pansin lamang sa daan-daang pag-uulit (RecyclerView na may sampu-sampung libong elemento). Para sa karaniwang screen (1–3 FrameLayout), ang pagkakaiba ay nasa microseconds at hindi nakakaapekto sa UX. Ang ConstraintLayout ay ang unibersal na pagpipilian para sa 95% ng mga gawain.

Buod

  • FrameLayout — ang pinakasimpleng ViewGroup ng Android para sa pagpapatong ng mga elemento at mga lalagyan ng placeholder na may pinakamababang overhead.
  • Pagpapatong ng mga layer — bawat bagong child ay iginuhit sa ibabaw ng nauna; ang huling idineklara sa XML ay ang nasa itaas.
  • Foreground — drawable sa ibabaw ng lahat ng anak para sa mga epekto ng overlay, pag-mask, at ripple animation.
  • measureAllChildren — pag-disable (false) ay nag-aalis ng mga elementong GONE mula sa pagkalkula ng laki, pinapabilis ang rendering ng 20–60%.
  • layout_gravity — ang tanging mekanismo ng pagpoposisyon: top, bottom, left, right, center, at mga kumbinasyon nito.
  • Lalagyan ng fragment — ang pinakakaraniwang kaso ng paggamit: FrameLayout (o FragmentContainerView) para sa FragmentTransaction.replace().
  • Pagganap — ang pinakamabilis na lalagyan para sa 1 child; para sa mga kumplikadong layout, ito ay mas mababa sa ConstraintLayout.

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.

Pag-usapan ang proyekto

Basahin din