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
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 ä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.
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%.
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).
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.
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å.
<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.
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).
<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å.
FrameLayout som standardbehållare för FragmentTransaction. Aktiviteten ersätter fragment i denna behållare beroende på navigering.
<FrameLayout
android:id="@+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent" />
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.
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
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.
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.
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.
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
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.
Läs också