FrameLayout: kernconcepten, eenvoudige positionering in Android

Auteur: IT Sectr Gepubliceerd: 2026-02-24 Leestijd: 8 min

Leer de kernconcepten van FrameLayout — de eenvoudigste ViewGroup in de Android SDK, ontworpen voor het plaatsen van één onderliggend element (meestal) of het over elkaar heen leggen van meerdere elementen. FrameLayout is handig voor placeholder-containers, fragmenten, laadindicatoren en voorgrondelementen. Het beheert de positionering van kinderen niet — elk volgend element wordt boven het vorige getekend en hun positie wordt bepaald door layout_gravity (left, top, right, bottom, center). Basisscenario's worden beschreven in de FrameLayout API Reference.

Belangrijkste punten

  • Lagen stapelen — FrameLayout plaatst elementen opeenvolgend boven elkaar; het laatst gedeclareerde in XML wordt boven allemaal getekend.
  • Foreground — het attribuut android:foreground maakt het mogelijk een drawable over alle onderliggende elementen heen te leggen, handig voor effecten en maskering.
  • measureAllChildren — standaard meet FrameLayout alle kinderen, zelfs onzichtbare (GONE). Uitschakelen versnelt het renderen met 20–60%.
  • layout_gravity — de enige manier om een onderliggend element binnen FrameLayout te positioneren: top, bottom, left, right, center.
  • Gebruik met Fragment — FrameLayout is de standaardcontainer voor FragmentTransaction.replace(), die inhoud vervangt zonder de activiteit opnieuw aan te maken.

Wat is FrameLayout?

FrameLayout is de eenvoudigste ViewGroup in de Android SDK, ontworpen om een schermgebied te blokkeren en één onderliggende view weer te geven (of meerdere over elkaar heen te leggen). In tegenstelling tot LinearLayout (opeenvolgende plaatsing) en RelativeLayout (relatieve positionering), verandert FrameLayout de positie van kinderen niet — elke nieuwe child wordt standaard in de linkerbovenhoek (0,0) geplaatst en boven de vorige getekend.

FrameLayout verscheen in API Level 1 en blijft de lichtste Android-container: het overschrijft onMeasure niet met complexe logica en voert een minimaal aantal layoutbewerkingen uit. Volgens de Android Performance Blog voert FrameLayout onLayout in één keer uit en voegt het praktisch geen overhead toe in vergelijking met het direct plaatsen van een View. Dit maakt het ideaal voor containers waar snelheid belangrijk is: RecyclerView-itemlayouts (in combinatie met ConstraintLayout voor positionering), fragmentcontainers, overleylagen.

De standaardgrootte van FrameLayout wordt bepaald door het grootste onderliggende element (als match_parent niet is ingesteld). Als er geen child is opgegeven, krimpt FrameLayout naar (0,0). Het attribuut android:measureAllChildren (paragraaf hieronder) wijzigt dit gedrag.

FrameLayout in de Android ViewGroup-hiërarchie

FrameLayout erft van ViewGroup en is de directe ouder van vele gespecialiseerde containers: FragmentContainerView (fragmenten), CardView (kaarten met schaduw), ScrollView (met één child), NestedScrollView. Bij het maken van een Activity met fragmentnavigatie gebruikt de standaard Android Studio-sjabloon FrameLayout (of FragmentContainerView) als de hoofdcontainer voor fragmenten.

Foreground en measureAllChildren

android:foreground — FrameLayout-attribuut dat een drawable specificeert die over alle onderliggende elementen wordt getekend. In tegenstelling tot background (onder kinderen), wordt foreground boven de inhoud weergegeven en kan transparant zijn. Gebruikt voor: overlay-effecten bij indrukken (ripple via ?attr/selectableItemBackground), maskeren van afbeeldingen, weergeven van statusindicatoren (selectievinkje boven afbeelding).

Foreground ondersteunt standaard drawable-bronnen: ColorDrawable, ShapeDrawable, RippleDrawable, LayerDrawable. Vanaf API 23+ is android:foregroundGravity beschikbaar voor het positioneren van foreground (fill, center, top, bottom). In de "vul"-modus (fill) wordt foreground over de gehele FrameLayout uitgerekt; in de centrummodus wordt het in het midden getekend.

android:measureAllChildren — boolean attribuut (standaard true) dat bepaalt of alle onderliggende elementen moeten worden gemeten bij het berekenen van de FrameLayout-grootte. Indien true (standaard), houdt FrameLayout rekening met de afmetingen van alle kinderen, inclusief GONE (met grootte 0). Indien false, meet FrameLayout alleen VISIBLE en INVISIBLE kinderen — GONE-elementen worden uitgesloten van de berekening. Volgens Google I/O 2019 versnelt het uitschakelen van measureAllChildren voor containers met veel GONE-elementen (bijv. lijsten met zichtbaarheidsschakeling) de initiële weergave met 20–60%.

layout_gravity: positionering binnen FrameLayout

android:layout_gravity — attribuut van het onderliggende element van FrameLayout (en andere ViewGroups) dat zijn positie binnen de container bepaalt. In FrameLayout is layout_gravity de enige manier om de positie van een onderliggend element te beheren, omdat FrameLayout geen eigen positioneringsregels (zoals RelativeLayout) of richting (zoals LinearLayout) biedt.

Mogelijke waarden: top, bottom, left, right, center, center_horizontal, center_vertical, fill, fill_horizontal, fill_vertical, clip_horizontal, clip_vertical. Worden gecombineerd met |: android:layout_gravity="bottom|center_horizontal" — het element wordt tegen de onderrand gedrukt en horizontaal gecentreerd. Voor elementen die kleiner zijn dan FrameLayout, bepaalt layout_gravity hun positie in de vrije ruimte.

Als layout_gravity niet is ingesteld, wordt het element standaard in de linkerbovenhoek (top|left) geplaatst. Voor een FrameLayout met meerdere kinderen kan elk zijn eigen layout_gravity hebben — één element kan in de linkerbovenhoek zijn, een ander in de rechteronderhoek, een derde in het midden. Dit maakt eenvoudige overlays mogelijk (bijv. een sluitkruis boven een afbeelding).

Verschil tussen gravity en layout_gravity

android:gravity (ouderattribuut) lijnt de inhoud binnen FrameLayout uit — bijvoorbeeld tekst binnen TextView. android:layout_gravity (kindattribuut) lijnt het element zelf uit binnen FrameLayout. In de context van FrameLayout bepaalt gravity hoe kinderen standaard worden gerangschikt (analoog aan layout_gravity voor alle kinderen tegelijk), maar layout_gravity van elk specifiek element overschrijft de ouderlijke waarde.

Voorbeelden: XML en gebruiksscenario's

Voorbeeld 1: Basisoverlay — label op afbeelding

Afbeelding en tekstlabel in de rechteronderhoek. FrameLayout bevat een ImageView op volledig scherm en een TextView met layout_gravity="bottom|end" voor positionering erbovenop.

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>

ImageView beslaat de gehele FrameLayout (200dp hoogte). TextView met layout_gravity="bottom|end" wordt in de rechteronderhoek boven de afbeelding geplaatst. elevation=2dp voegt schaduw toe onder het label en scheidt het visueel van de afbeelding. Dit is een minimaal voorbeeld dat in LinearLayout een geneste container of aangepaste code zou vereisen.

Voorbeeld 2: Laadindicator (voortgangsbalk boven inhoud)

Scherm met inhoud en een voortgangsbalk in het midden die verschijnt tijdens het laden. FrameLayout bevat twee elementen: de inhoud en een ProgressBar met visibility="gone" (geschakeld in 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="Geladen inhoud"
        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>

ProgressBar is standaard verborgen (gone). Bij het starten van het laden wordt in code findViewById(R.id.loading_spinner).visibility = View.VISIBLE aangeroepen — de spinner verschijnt in het midden boven de inhoud. Na het laden — .visibility = View.GONE. FrameLayout zorgt voor overlay zonder de positie van de inhoud te wijzigen — de tekst verschuift niet bij het verschijnen van de spinner, omdat ProgressBar erboven wordt getekend.

Voorbeeld 3: Fragmentcontainer

FrameLayout als standaardcontainer voor FragmentTransaction. De activiteit vervangt fragmenten in deze container afhankelijk van de navigatie.

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 als fragmentcontainer — de lichtste manier om Fragment Navigation te ondersteunen. FragmentContainerView (overerfd van FrameLayout) wordt aanbevolen met Navigation Component 2.4+, maar eenvoudige FrameLayout blijft geldig voor handmatige FragmentTransaction. Het belangrijkste voordeel — FragmentTransaction.replace() vervangt de inhoud volledig zonder de activiteit te beïnvloeden.

Wanneer FrameLayout gebruiken

FrameLayout is optimaal voor vier scenario's: fragmentcontainer (FragmentContainerView of FrameLayout), laad-overlay (ProgressBar boven inhoud), kaartlabels (markering op afbeelding), placeholder-container voor ViewStub (lazy loading).

Niet geschikt voor: complexe positionering van meerdere elementen (gebruik ConstraintLayout), sequentiële lijsten (LinearLayout of RecyclerView), dynamische layouts met wijziging van de volgorde van elementen.

FrameLayout als root-element van een scherm — slechte praktijk als het scherm meer dan 2–3 elementen bevat. Gebruik ConstraintLayout voor de root-container — het geeft meer controle over positionering zonder prestatieverlies. Gebruik FrameLayout alleen voor onderliggende blokken waar overlay of een placeholder nodig is.

Veelgestelde vragen

Wat is het verschil tussen FrameLayout en ConstraintLayout?

FrameLayout — een minimalistische container zonder positioneringssysteem (alleen layout_gravity), bedoeld voor het over elkaar heen leggen van elementen. ConstraintLayout — een volledig layoutsysteem met constraints, kettingen, barrières, procentuele afmetingen en ondersteuning voor MotionLayout. FrameLayout is sneller voor eenvoudige gevallen (1 child of overlay); ConstraintLayout is verplicht voor complexe layouts. Keuze: FrameLayout voor laad-overlay en fragmentcontainer; ConstraintLayout voor al het andere.

Hoe zorg ik dat FrameLayout alleen de ruimte van de grootste child inneemt?

Stel de FrameLayout-grootte in op wrap_content op de gewenste as (android:layout_width="wrap_content" en/of android:layout_height="wrap_content"). In dit geval past FrameLayout zich aan aan de grootte van het grootste onderliggende element. Als alle kinderen kleiner zijn dan FrameLayout, blijft de overtollige ruimte leeg. Gebruik voor nauwkeurige controle match_parent met vaste padding.

Waarom overlappen elementen in FrameLayout elkaar?

Dit is normaal gedrag van FrameLayout — het verdeelt kinderen niet in de ruimte, maar tekent ze opeenvolgend boven elkaar. Als u wilt dat elementen elkaar niet overlappen, gebruik dan een andere container (LinearLayout, ConstraintLayout). Gedeeltelijke overlapping met controle over de tekenvolgorde bereikt u met layout_gravity voor verschuiving en elevation voor Z-order.

Wat is sneller: FrameLayout of ConstraintLayout?

FrameLayout is sneller voor zeer eenvoudige gevallen — één onderliggend element, zonder complexe positionering. FrameLayout voert onMeasure in minimale tijd uit, zonder constraints te berekenen. Het verschil is echter alleen merkbaar bij honderden herhalingen (RecyclerView met tienduizenden elementen). Voor een normaal scherm (1–3 FrameLayouts) bedraagt het verschil microseconden en heeft het geen invloed op UX. ConstraintLayout is de universele keuze voor 95% van de taken.

Samenvatting

  • FrameLayout — de eenvoudigste Android ViewGroup voor het stapelen van elementen en placeholder-containers met minimale overhead.
  • Lagen stapelen — elke nieuwe child wordt boven de vorige getekend; de laatst gedeclareerde in XML is de bovenste.
  • Foreground — drawable boven alle kinderen voor overlay-effecten, maskering en ripple-animatie.
  • measureAllChildren — uitschakelen (false) sluit GONE-elementen uit van de grootteberekening, waardoor renderen met 20–60% versnelt.
  • layout_gravity — het enige positioneringsmechanisme: top, bottom, left, right, center en combinaties daarvan.
  • Fragmentcontainer — het meest voorkomende gebruik: FrameLayout (of FragmentContainerView) voor FragmentTransaction.replace().
  • Prestaties — de snelste container voor 1 child; voor complexe layouts doet het onder voor ConstraintLayout.

We ontwikkelen een mobiele applicatie turnkey

IT Sectr creëert sinds 2017 iOS- en Android-applicaties voor startups en bedrijven. We adviseren u en stellen de beste oplossing voor.

Bespreek het project

Lees ook