FrameLayout: nyckelbegrepp, enkel positionering i Android

Författare: IT Sectr Publicerad: 2026-02-24 Lästid: 8 min

Lär dig nyckelbegreppen för FrameLayout — den enklaste ViewGroup i Android SDK, utformad för att placera ett underordnat element (vanligtvis) eller överlagra flera element. FrameLayout är praktisk för platshållarbehållare, fragment, laddningsindikatorer och förgrundselement. Den hanterar inte barnens placering — varje efterföljande element ritas ovanpå det föregående och deras position bestäms av layout_gravity (left, top, right, bottom, center). Grundläggande scenarier beskrivs i FrameLayout API Reference.

Huvudpunkter

  • Lageröverlagring — FrameLayout placerar element sekventiellt ovanpå varandra; det senast deklarerade i XML ritas högst upp.
  • Forground — attributet android:foreground gör det möjligt att lägga en drawable ovanpå alla underordnade element, användbart för effekter och maskering.
  • measureAllChildren — som standard mäter FrameLayout alla barn, även osynliga (GONE). Inaktivering snabbar upp renderingen med 20–60%.
  • layout_gravity — det enda sättet att positionera ett underordnat element inuti FrameLayout: top, bottom, left, right, center.
  • Användning med Fragment — FrameLayout är standardbehållaren för FragmentTransaction.replace(), som ersätter innehåll utan att återskapa aktiviteten.

Vad är FrameLayout?

FrameLayout är den enklaste ViewGroup i Android SDK, utformad för att blockera ett skärmområde och visa en underordnad vy (eller överlagra flera). Till skillnad från LinearLayout (sekventiell placering) och RelativeLayout (relativ positionering) ändrar FrameLayout inte barnens position — varje ny child placeras som standard i det övre vänstra hörnet (0,0) och ritas ovanpå den föregående.

FrameLayout dök upp i API Level 1 och förblir den lättaste Android-behållaren: den åsidosätter inte onMeasure med komplex logik och utför ett minimalt antal layoutoperationer. Enligt Android Performance Blog utför FrameLayout onLayout i en enda passering och tillför praktiskt taget ingen overhead jämfört med direkt placering av View. Detta gör den till ett idealiskt val för behållare där hastighet är viktig: RecyclerView-objektlayouter (i kombination med ConstraintLayout för positionering), fragmentbehållare, överlagringslager.

Standardstorleken för FrameLayout bestäms av det största underordnade elementet (om match_parent inte är inställd). Om inget child anges krymper FrameLayout till (0,0). Attributet android:measureAllChildren (avsnitt nedan) ändrar detta beteende.

FrameLayout i Android ViewGroup-hierarkin

FrameLayout ärver från ViewGroup och är den direkta föräldern till många specialiserade behållare: FragmentContainerView (fragment), CardView (kort med skugga), ScrollView (med ett child), NestedScrollView. När du skapar en Activity med Fragment-navigering använder Android Studios standardmall FrameLayout (eller FragmentContainerView) som huvudbehållare för fragment.

Forground och measureAllChildren

android:foreground — FrameLayout-attribut som anger en drawable som ritas ovanpå alla underordnade element. Till skillnad från background (under barn) visas foreground ovanför innehållet och kan vara transparent. Används för: överlagringseffekter vid tryckning (ripple via ?attr/selectableItemBackground), maskering av bilder, visning av statusindikatorer (markeringsbock ovanför bild).

Foreground stöder vanliga drawable-resurser: ColorDrawable, ShapeDrawable, RippleDrawable, LayerDrawable. Från API 23+ är android:foregroundGravity tillgänglig för positionering av foreground (fill, center, top, bottom). I fyllningsläge (fill) sträcks foreground över hela FrameLayout; i centerläge ritas den i mitten.

android:measureAllChildren — booleskt attribut (standard true) som avgör om alla underordnade element ska mätas vid beräkning av FrameLayouts storlek. Om true (standard) tar FrameLayout hänsyn till storleken på alla barn, inklusive GONE (med storlek 0). Om false mäter FrameLayout endast VISIBLE och INVISIBLE barn — GONE-element utesluts från beräkningen. Enligt Google I/O 2019 snabbar inaktivering av measureAllChildren för behållare med många GONE-element (t.ex. listor med synlighetsväxling) upp den initiala renderingen med 20–60%.

layout_gravity: positionering inuti FrameLayout

android:layout_gravity — attribut för det underordnade elementet i FrameLayout (och andra ViewGroup) som bestämmer dess position inuti behållaren. I FrameLayout är layout_gravity det enda sättet att kontrollera positionen för ett underordnat element, eftersom FrameLayout inte tillhandahåller egna positioneringsregler (som RelativeLayout) eller riktning (som LinearLayout).

Möjliga värden: top, bottom, left, right, center, center_horizontal, center_vertical, fill, fill_horizontal, fill_vertical, clip_horizontal, clip_vertical. Kombineras med |: android:layout_gravity="bottom|center_horizontal" — elementet trycks mot nedre kanten och centreras horisontellt. För element vars storlek är mindre än FrameLayout bestämmer layout_gravity deras position i det fria utrymmet.

Om layout_gravity inte är inställd placeras elementet som standard i övre vänstra hörnet (top|left). För en FrameLayout som innehåller flera barn kan varje ha sin egen layout_gravity — ett element kan vara i det övre vänstra hörnet, ett annat i det nedre högra, ett tredje i mitten. Detta möjliggör enkla överlagringar (t.ex. ett stängningskryss ovanför en bild).

Skillnad mellan gravity och layout_gravity

android:gravity (föräldraattribut) justerar innehållet inuti FrameLayout — till exempel text inuti TextView. android:layout_gravity (barnattribut) justerar själva elementet inuti FrameLayout. I FrameLayouts sammanhang bestämmer gravity hur barn placeras som standard (motsvarande layout_gravity för alla barn samtidigt), men layout_gravity för varje specifikt element åsidosätter förälderns värde.

Exempel: XML och användningsfall

Exempel 1: Grundläggande överlagring — etikett på bild

Bild och texterikett i nedre högra hörnet. FrameLayout innehåller en ImageView på helskärm och en TextView med layout_gravity="bottom|end" för positionering ovanpå.

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 upptar hela FrameLayout (200dp höjd). TextView med layout_gravity="bottom|end" placeras i nedre högra hörnet ovanför bilden. elevation=2dp lägger till skugga under etiketten och skiljer den visuellt från bilden. Detta är ett minimalt exempel som i LinearLayout skulle kräva en nästlad behållare eller anpassad kod.

Exempel 2: Laddningsindikator (förloppsindikator ovanför innehåll)

Skärm med innehåll och en förloppsindikator i mitten som visas vid laddning. FrameLayout innehåller två element: innehållet och en ProgressBar med visibility="gone" (växlas i kod).

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="Laddat innehåll"
        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 är som standard dold (gone). Vid laddningsstart anropas i koden findViewById(R.id.loading_spinner).visibility = View.VISIBLE — spinnern visas i mitten ovanför innehållet. Efter laddning — .visibility = View.GONE. FrameLayout säkerställer överlagring utan att ändra innehållets position — texten flyttas inte när spinnern visas, eftersom ProgressBar ritas ovanpå.

Exempel 3: Fragmentbehållare

FrameLayout som standardbehållare för FragmentTransaction. Aktiviteten ersätter fragment i denna behållare beroende på navigering.

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 som fragmentbehållare — det lättaste sättet att stödja Fragment Navigation. FragmentContainerView (arvinge till FrameLayout) rekommenderas med Navigation Component 2.4+, men enkel FrameLayout förblir giltig för manuella FragmentTransaction. Den viktigaste fördelen — FragmentTransaction.replace() ersätter innehållet helt utan att påverka aktiviteten.

När ska man använda FrameLayout

FrameLayout är optimal för fyra scenarier: fragmentbehållare (FragmentContainerView eller FrameLayout), laddningsöverlagring (ProgressBar ovanför innehåll), kortetiketter (markering på bild), platshållarbehållare för ViewStub (lat laddning).

Inte lämplig för: komplex positionering av flera element (använd ConstraintLayout), sekventiella listor (LinearLayout eller RecyclerView), dynamiska layouter med ändring av elementordning.

FrameLayout som rotelement på skärmen — dålig praxis om skärmen innehåller mer än 2–3 element. För rotbehållaren, använd ConstraintLayout — den ger mer kontroll över positionering utan prestandaförlust. Använd FrameLayout endast för underordnade block där överlagring eller platshållare behövs.

Vanliga frågor

Vad är skillnaden mellan FrameLayout och ConstraintLayout?

FrameLayout — en minimalistisk behållare utan positioneringssystem (endast layout_gravity), avsedd för överlagring av element. ConstraintLayout — ett fullfjädrat layout-system med begränsningar, kedjor, barriärer, procentuella storlekar och stöd för MotionLayout. FrameLayout är snabbare för enkla fall (1 child eller overlay); ConstraintLayout är obligatorisk för komplexa layouter. Val: FrameLayout för laddningsöverlagring och fragmentbehållare; ConstraintLayout för allt annat.

Hur får jag FrameLayout att bara uppta det största child-utrymmet?

Ställ in FrameLayouts storlek på wrap_content på önskad axel (android:layout_width="wrap_content" och/eller android:layout_height="wrap_content"). I detta fall anpassar sig FrameLayout till storleken på det största underordnade elementet. Om alla barn är mindre än FrameLayout förblir överskottsutrymmet tomt. För exakt kontroll, använd match_parent med fast padding.

Varför överlappar element i FrameLayout varandra?

Detta är normalt beteende för FrameLayout — den fördelar inte barn i utrymmet utan ritar dem sekventiellt ovanpå varandra. Om du vill att element inte ska överlappa varandra, använd en annan behållare (LinearLayout, ConstraintLayout). För partiell överlappning med kontroll över ritordningen, använd layout_gravity för förskjutning och elevation för Z-ordning.

Vad är snabbare: FrameLayout eller ConstraintLayout?

FrameLayout är snabbare för extremt enkla fall — ett underordnat element, utan komplex positionering. FrameLayout utför onMeasure på minimal tid, utan att beräkna begränsningar. Skillnaden är dock märkbar endast vid hundratals upprepningar (RecyclerView med tiotusentals element). För en vanlig skärm (1–3 FrameLayout) är skillnaden i mikrosekunder och påverkar inte UX. ConstraintLayout är det universella valet för 95% av uppgifterna.

Sammanfattning

  • FrameLayout — den enklaste Android ViewGroup för överlagring av element och platshållarbehållare med minimal overhead.
  • Lageröverlagring — varje ny child ritas ovanpå den föregående; den senast deklarerade i XML är högst upp.
  • Forground — drawable ovanför alla barn för överlagringseffekter, maskering och ripple-animering.
  • measureAllChildren — inaktivering (false) utesluter GONE-element från storleksberäkning, snabbar upp rendering med 20–60%.
  • layout_gravity — den enda positioneringsmekanismen: top, bottom, left, right, center och deras kombinationer.
  • Fragmentbehållare — det vanligaste användningsfallet: FrameLayout (eller FragmentContainerView) för FragmentTransaction.replace().
  • Prestanda — den snabbaste behållaren för 1 child; för komplexa layouter underlägsen ConstraintLayout.

Vi utvecklar en mobil applikation nyckelfärdigt

IT Sectr skapar iOS- och Android-applikationer för startups och företag sedan 2017. Vi ger dig råd och föreslår den bästa lösningen.

Diskutera projektet

Läs också