FrameLayout: alapfogalmak, egyszerű pozicionálás Androidban

Szerző: IT Sectr Megjelenés: 2026-02-24 Olvasási idő: 8 perc

Ismerje meg a FrameLayout alapfogalmait — a legegyszerűbb ViewGroup az Android SDK-ban, amely egy gyermekelem elhelyezésére (általában) vagy több elem egymásra helyezésére szolgál. A FrameLayout kényelmes helyőrző konténerekhez, fragmensekhez, betöltésjelzőkhöz és előtér-elemekhez. Nem kezeli a gyermekek elhelyezését — minden következő elem az előző fölé rajzolódik, pozíciójukat pedig a layout_gravity határozza meg (left, top, right, bottom, center). Az alapszcenáriók a FrameLayout API Reference-ben találhatók.

Főbb pontok

  • Rétegek egymásra helyezése — a FrameLayout egymás után, egymás fölé helyezi az elemeket; a XML-ben utoljára deklarált rajzolódik a legfelülre.
  • Foreground — az android:foreground attribútum lehetővé teszi egy drawable elhelyezését az összes gyermekelem fölött, hasznos effektekhez és maszkoláshoz.
  • measureAllChildren — alapértelmezés szerint a FrameLayout az összes gyermeket méri, még a láthatatlanokat is (GONE). Kikapcsolása 20–60%-kal gyorsítja a renderelést.
  • layout_gravity — az egyetlen mód a gyermekelem pozicionálására a FrameLayouton belül: top, bottom, left, right, center.
  • Használat Fragment-tel — a FrameLayout szabványos konténer a FragmentTransaction.replace()-hez, amely az aktivitás újraépítése nélkül cseréli a tartalmat.

Mi az a FrameLayout?

A FrameLayout a legegyszerűbb ViewGroup az Android SDK-ban, amely egy képernyőterület blokkolására és egy gyermek nézet megjelenítésére (vagy több egymásra helyezésére) szolgál. A LinearLayout-tól (szekvenciális elhelyezés) és a RelativeLayout-tól (relatív pozicionálás) eltérően a FrameLayout nem változtatja meg a gyermekek pozícióját — minden új child alapértelmezés szerint a bal felső sarokba (0,0) kerül, és az előző fölé rajzolódik.

A FrameLayout az API Level 1-ben jelent meg, és a mai napig a legkönnyebb Android konténer maradt: nem írja felül az onMeasure-t összetett logikával, és minimális számú layout műveletet végez. Az Android Performance Blog szerint a FrameLayout egy menetben végrehajtja az onLayout-ot, és gyakorlatilag nincs többletterhelése a View közvetlen elhelyezéséhez képest. Ez ideális választássá teszi olyan konténerekhez, ahol a sebesség számít: RecyclerView item-layoutok (ConstraintLayout-tal párosítva a pozicionáláshoz), fragment konténerek, átfedő rétegek.

A FrameLayout alapértelmezett méretét a legnagyobb gyermekelem határozza meg (ha nincs match_parent beállítva). Ha nincs megadva child, a FrameLayout (0,0)-ra zsugorodik. Az android:measureAllChildren attribútum (lásd alább) megváltoztatja ezt a viselkedést.

A FrameLayout az Android ViewGroup hierarchiában

A FrameLayout a ViewGroup-ból származik, és számos speciális konténer közvetlen szülője: FragmentContainerView (fragmensek), CardView (árnyékos kártyák), ScrollView (egy child-dal), NestedScrollView. Fragment navigációval rendelkező Activity létrehozásakor az Android Studio alapértelmezett sablonja a FrameLayout-ot (vagy FragmentContainerView-t) használja a fragmensek fő konténereként.

Foreground és measureAllChildren

android:foreground — a FrameLayout attribútuma, amely egy drawable-t határoz meg, amely az összes gyermekelem fölött rajzolódik. A background-tól (a gyermekek alatt) eltérően a foreground a tartalom fölött jelenik meg, és lehet átlátszó. Használata: átfedési effektusok lenyomáskor (ripple ?attr/selectableItemBackground segítségével), képek maszkolása, állapotjelzők megjelenítése (kijelölő pipa a kép fölött).

A foreground támogatja a szabványos drawable erőforrásokat: ColorDrawable, ShapeDrawable, RippleDrawable, LayerDrawable. API 23+-tól elérhető az android:foregroundGravity a foreground pozicionálásához (fill, center, top, bottom). "Kitöltés" (fill) módban a foreground az egész FrameLayout-ra nyúlik; center módban a középpontba rajzolódik.

android:measureAllChildren — logikai attribútum (alapértelmezett true), amely meghatározza, hogy a FrameLayout méretének kiszámításakor az összes gyermekelem mérése szükséges-e. Ha true (alapértelmezett), a FrameLayout figyelembe veszi az összes gyermek méretét, beleértve a GONE (0 méretű) elemeket is. Ha false, a FrameLayout csak a VISIBLE és INVISIBLE gyermekeket méri — a GONE elemek kizárásra kerülnek a számításból. A Google I/O 2019 szerint a measureAllChildren kikapcsolása sok GONE elemet tartalmazó konténereknél (pl. láthatóságot váltó listák) 20–60%-kal gyorsítja a kezdeti renderelést.

layout_gravity: pozicionálás a FrameLayouton belül

android:layout_gravity — a FrameLayout (és más ViewGroup-ok) gyermekelemének attribútuma, amely meghatározza annak pozícióját a konténeren belül. A FrameLayoutban a layout_gravity az egyetlen mód a gyermekelem pozíciójának szabályozására, mivel a FrameLayout nem rendelkezik saját pozicionálási szabályokkal (mint a RelativeLayout) vagy iránnyal (mint a LinearLayout).

Lehetséges értékek: top, bottom, left, right, center, center_horizontal, center_vertical, fill, fill_horizontal, fill_vertical, clip_horizontal, clip_vertical. | jellel kombinálhatók: android:layout_gravity="bottom|center_horizontal" — az elem az alsó szélhez van nyomva és vízszintesen középre igazítva. Azon elemek esetében, amelyek mérete kisebb, mint a FrameLayout, a layout_gravity határozza meg a pozíciójukat a szabad helyen.

Ha a layout_gravity nincs beállítva, az elem alapértelmezés szerint a bal felső sarokba (top|left) kerül. Több gyermeket tartalmazó FrameLayout esetén mindegyiknek lehet saját layout_gravity-je — az egyik elem lehet a bal felső sarokban, a másik a jobb alsó sarokban, a harmadik a középpontban. Ez egyszerű átfedések létrehozását teszi lehetővé (pl. egy bezáró X jel a kép fölött).

A gravity és a layout_gravity közötti különbség

android:gravity (szülő attribútum) a FrameLayouton belüli tartalmat igazítja — például a szöveget a TextView-n belül. android:layout_gravity (gyermek attribútum) magát az elemet igazítja a FrameLayouton belül. A FrameLayout kontextusában a gravity határozza meg, hogy a gyermekek alapértelmezés szerint hogyan helyezkedjenek el (a layout_gravity megfelelője az összes gyermekre egyszerre), de az egyes elemek layout_gravity-je felülírja a szülő értékét.

Példák: XML és használati esetek

1. példa: Alapvető átfedés — címke a képen

Kép és szöveges címke a jobb alsó sarokban. A FrameLayout egy teljes képernyős ImageView-t és egy layout_gravity="bottom|end" beállítású TextView-t tartalmaz a fölé pozicionáláshoz.

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>

Az ImageView elfoglalja a teljes FrameLayout-ot (200dp magasság). A layout_gravity="bottom|end" beállítású TextView a kép fölött a jobb alsó sarokba kerül. Az elevation=2dp árnyékot ad a címke alá, vizuálisan elválasztva azt a képtől. Ez egy minimális példa, amely a LinearLayout-ban beágyazott konténert vagy egyedi kódot igényelne.

2. példa: Betöltésjelző (folyamatjelző a tartalom fölött)

Képernyő tartalommal és egy középen lévő folyamatjelzővel, amely betöltéskor jelenik meg. A FrameLayout két elemet tartalmaz: a tartalmat és egy visibility="gone" beállítású ProgressBar-t (kódban kapcsolható).

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="Betöltött tartalom"
        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>

A ProgressBar alapértelmezés szerint rejtett (gone). A betöltés megkezdésekor a kódban meghívódik findViewById(R.id.loading_spinner).visibility = View.VISIBLE — a spinner megjelenik a középpontban a tartalom fölött. Betöltés után — .visibility = View.GONE. A FrameLayout biztosítja az átfedést a tartalom pozíciójának megváltoztatása nélkül — a szöveg nem mozdul el a spinner megjelenésekor, mivel a ProgressBar fölé rajzolódik.

3. példa: Fragment konténer

FrameLayout szabványos konténerként a FragmentTransaction számára. Az aktivitás a navigációtól függően cseréli a fragmenseket ezen a konténeren belül.

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 fragment konténerként — a legkönnyebb módja a Fragment Navigation támogatásának. A FragmentContainerView (a FrameLayout leszármazottja) a Navigation Component 2.4+-ban ajánlott, de az egyszerű FrameLayout továbbra is érvényes a manuális FragmentTransaction-okhoz. A fő előny — a FragmentTransaction.replace() teljesen lecseréli a tartalmat anélkül, hogy befolyásolná az Activity-t.

Mikor használjuk a FrameLayout-ot

A FrameLayout négy szcenárióhoz optimális: fragment konténer (FragmentContainerView vagy FrameLayout), betöltési átfedés (ProgressBar a tartalom fölött), kártyacímkék (jelölés a képen), helyőrző konténer ViewStub-hoz (lustán betöltés).

Nem alkalmas: több elem összetett pozicionálására (használjon ConstraintLayout-ot), szekvenciális listákhoz (LinearLayout vagy RecyclerView), dinamikus elrendezésekhez az elemek sorrendjének változásával.

A FrameLayout a képernyő gyökérelemeként — rossz gyakorlat, ha a képernyő több mint 2–3 elemet tartalmaz. Gyökér konténerként használja a ConstraintLayout-ot — több irányítást ad a pozicionálás fölött teljesítményveszteség nélkül. A FrameLayout-ot csak olyan gyermekblokkokhoz használja, ahol átfedésre vagy helyőrzőre van szükség.

Gyakran ismételt kérdések

Mi a különbség a FrameLayout és a ConstraintLayout között?

A FrameLayout egy minimalista konténer pozicionálási rendszer nélkül (csak layout_gravity), elemek egymásra helyezésére tervezve. A ConstraintLayout egy teljes elrendezési rendszer kényszerekkel, láncokkal, korlátokkal, százalékos méretekkel és MotionLayout támogatással. A FrameLayout gyorsabb egyszerű esetekben (1 child vagy overlay); a ConstraintLayout kötelező az összetett elrendezésekhez. Választás: FrameLayout a betöltési átfedéshez és fragment konténerhez; ConstraintLayout minden máshoz.

Hogyan érhetem el, hogy a FrameLayout csak a legnagyobb child helyét foglalja?

Állítsa a FrameLayout méretét wrap_content-re a kívánt tengelyen (android:layout_width="wrap_content" és/vagy android:layout_height="wrap_content"). Ebben az esetben a FrameLayout a legnagyobb gyermekelem méretéhez igazodik. Ha az összes gyermek kisebb, mint a FrameLayout, a felesleges hely üresen marad. Pontos szabályozáshoz használjon match_parent-t fix padding-gal.

Miért fedik egymást az elemek a FrameLayout-ban?

Ez a FrameLayout normál viselkedése — nem osztja el a gyermekeket a térben, hanem egymás után, egymás fölé rajzolja őket. Ha azt szeretné, hogy az elemek ne fedjék egymást, használjon másik konténert (LinearLayout, ConstraintLayout). Részleges átfedéshez a rajzolási sorrend szabályozásával használja a layout_gravity-t az eltoláshoz és az elevation-t a Z-order-hez.

Melyik gyorsabb: a FrameLayout vagy a ConstraintLayout?

A FrameLayout gyorsabb a maximálisan egyszerű esetekben — egy gyermekelem, összetett pozicionálás nélkül. A FrameLayout minimális idő alatt végrehajtja az onMeasure-t, számítás nélkül. A különbség azonban csak több száz ismétlésnél észlelhető (RecyclerView tízezernyi elemmel). Egy átlagos képernyőnél (1–3 FrameLayout) a különbség mikroszekundumokban mérhető, és nem befolyásolja az UX-t. A ConstraintLayout az univerzális választás a feladatok 95%-ához.

Összefoglalás

  • FrameLayout — a legegyszerűbb Android ViewGroup elemek egymásra helyezéséhez és helyőrző konténerekhez, minimális többletterheléssel.
  • Rétegek egymásra helyezése — minden új child az előző fölé rajzolódik; a XML-ben utoljára deklarált van legfelül.
  • Foreground — drawable az összes gyermek fölött átfedési effektekhez, maszkoláshoz és ripple animációhoz.
  • measureAllChildren — kikapcsolás (false) kizárja a GONE elemeket a méretszámításból, 20–60%-kal gyorsítva a renderelést.
  • layout_gravity — az egyetlen pozicionálási mechanizmus: top, bottom, left, right, center és kombinációik.
  • Fragment konténer — a leggyakoribb használati eset: FrameLayout (vagy FragmentContainerView) a FragmentTransaction.replace()-hez.
  • Teljesítmény — a leggyorsabb konténer 1 child esetén; összetett elrendezéseknél alulmarad a ConstraintLayout-tal szemben.

Kulcsrakész mobilalkalmazást fejlesztünk

Az IT Sectr 2017 óta készít iOS és Android alkalmazásokat induló vállalkozásoknak és vállalkozásoknak. Tanácsot adunk, és a legjobb megoldást javasoljuk.

Projekt megbeszélése

Olvassa el is