Learn the key concepts of FrameLayout — the simplest ViewGroup in Android SDK, designed to host a single child element (typically) or overlay multiple elements on top of each other. FrameLayout is convenient for placeholder containers, fragments, loading indicators, and foreground elements. It does not manage child positioning — each subsequent element draws on top of the previous one, and their position is determined by layout_gravity (left, top, right, bottom, center). Basic scenarios are described in the FrameLayout API Reference.
Key Takeaways
FrameLayout is the simplest ViewGroup in Android SDK, designed to block a screen area and display a single child view (or overlay several). Unlike LinearLayout (sequential placement) and RelativeLayout (relative positioning), FrameLayout does not alter child positions — each new child is placed in the top-left corner (0,0) by default and drawn on top of the previous one.
FrameLayout was introduced in API Level 1 and remains the lightest Android container: it does not override onMeasure with complex logic and performs a minimal number of layout operations. According to the Android Performance Blog, FrameLayout executes onLayout in a single pass and adds virtually no overhead compared to placing a View directly. This makes it an ideal choice for containers where speed matters: RecyclerView item layouts (paired with ConstraintLayout for positioning), Fragment containers, overlay layers.
FrameLayout's size defaults to the largest child element (if match_parent is not set). If no child is specified, FrameLayout collapses to (0,0). The android:measureAllChildren attribute (section below) changes this behavior.
FrameLayout inherits from ViewGroup and is the direct parent of many specialized containers: FragmentContainerView (fragments), CardView (cards with shadows), ScrollView (single child), NestedScrollView. When creating an Activity with Fragment navigation, the standard Android Studio template uses FrameLayout (or FragmentContainerView) as the root container for fragments.
android:foreground — a FrameLayout attribute that specifies a drawable drawn on top of all child elements. Unlike background (under children), foreground displays above the content and can be transparent. It is used for: overlay effects on press (ripple via ?attr/selectableItemBackground), image masking, status indicator display (selection checkmark over an image).
Foreground supports standard drawable resources: ColorDrawable, ShapeDrawable, RippleDrawable, LayerDrawable. Since API 23+, android:foregroundGravity is available for foreground positioning (fill, center, top, bottom). In fill mode, foreground stretches across the entire FrameLayout; in center mode, it draws in the center.
android:measureAllChildren — a boolean attribute (true by default) that determines whether to measure all child elements when calculating FrameLayout size. If true (default), FrameLayout accounts for the sizes of all children, including GONE (with size 0). If false, FrameLayout measures only VISIBLE and INVISIBLE children — GONE elements are excluded from calculation. According to Google I/O 2019, disabling measureAllChildren for containers with many GONE elements (e.g., toggling visibility lists) speeds up initial drawing by 20–60%.
android:layout_gravity — an attribute of a FrameLayout child element (and other ViewGroups) that defines its position inside the container. In FrameLayout, layout_gravity is the only way to control a child element's position, since FrameLayout does not provide its own positioning rules (like RelativeLayout) or direction (like LinearLayout).
Possible values: top, bottom, left, right, center, center_horizontal, center_vertical, fill, fill_horizontal, fill_vertical, clip_horizontal, clip_vertical. Combined via |: android:layout_gravity="bottom|center_horizontal" — the element is attached to the bottom edge and centered horizontally. For elements smaller than FrameLayout, layout_gravity determines their position in the free space.
If layout_gravity is not set, the element is placed in the top-left corner (top|left) by default. For a FrameLayout containing several children, each can have its own layout_gravity — one element can be in the top-left corner, another in the bottom-right corner, a third centered. This allows creating simple overlays (e.g., a close icon over an image).
android:gravity (parent attribute) aligns content inside FrameLayout — for example, text inside a TextView. android:layout_gravity (child attribute) aligns the element itself inside FrameLayout. In the context of FrameLayout, gravity defines how children are positioned by default (similar to layout_gravity for all children at once), but each element's layout_gravity overrides the parent value.
An image with a text label in the bottom-right corner. FrameLayout contains an ImageView filling the screen and a TextView with layout_gravity="bottom|end" for positioning on top.
<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>
The ImageView fills the entire FrameLayout (200dp height). The TextView with layout_gravity="bottom|end" is placed in the bottom-right corner over the image. elevation=2dp adds a shadow under the label, visually separating it from the image. This minimal example would require a nested container or custom code in LinearLayout.
A screen with content and a centered progress bar that appears during loading. FrameLayout contains two elements: content and a ProgressBar with visibility="gone" (toggled in code).
<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="Loaded content"
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>
The ProgressBar is hidden by default (gone). When loading starts, findViewById(R.id.loading_spinner).visibility = View.VISIBLE is called — the spinner appears in the center over the content. After loading — .visibility = View.GONE. FrameLayout provides overlay without shifting content position — the text does not move when the spinner appears, since the ProgressBar draws on top.
FrameLayout as a standard container for FragmentTransaction. The activity replaces fragments inside this container depending on navigation.
<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 as a fragment container is the lightest way to support Fragment Navigation. FragmentContainerView (a FrameLayout subclass) is recommended with Navigation Component 2.4+, but a plain FrameLayout remains valid for manual FragmentTransactions. The key advantage is that FragmentTransaction.replace() completely replaces the content without affecting the Activity.
FrameLayout is optimal for four scenarios: fragment container (FragmentContainerView or FrameLayout), loading overlay (ProgressBar over content), card labels (label on image), placeholder container for ViewStub (lazy loading).
Not suitable for: complex multi-element positioning (use ConstraintLayout), sequential lists (LinearLayout or RecyclerView), dynamic layouts with changing element order.
FrameLayout as a root screen element — bad practice if the screen contains more than 2–3 elements. For a root container, use ConstraintLayout — it gives more control over positioning without performance loss. Use FrameLayout only for child blocks where overlay or placeholder is needed.
Frequently Asked Questions
FrameLayout — a minimalistic container without a positioning system (only layout_gravity), designed for element overlay. ConstraintLayout — a full-featured layout system with constraints, chains, barriers, percentage dimensions, and MotionLayout support. FrameLayout is faster for simple cases (1 child or overlay); ConstraintLayout is required for complex layouts. Choice: FrameLayout for loading overlay and fragment container; ConstraintLayout for everything else.
Set FrameLayout size to wrap_content on the desired axis (android:layout_width="wrap_content" and/or android:layout_height="wrap_content"). FrameLayout will then adjust to the size of the largest child element. If all children are smaller than FrameLayout, excess space remains empty. For precise control, use match_parent with fixed padding.
This is FrameLayout's intended behavior — it does not distribute children in space but draws them sequentially on top of each other. If you want elements not to overlap, use another container (LinearLayout, ConstraintLayout). For partial overlap with control over the drawing order, use layout_gravity for offset and elevation for Z-order.
FrameLayout is faster for the simplest cases — one child element, no complex positioning. FrameLayout performs onMeasure in minimal time without calculating constraints. However, the difference is noticeable only at hundreds of repetitions (RecyclerView with tens of thousands of items). For a typical screen (1–3 FrameLayouts), the difference is microseconds and does not affect UX. ConstraintLayout is the universal choice for 95% of tasks.
Summary
We will develop a mobile application turnkey
IT Sectr creates iOS and Android applications for startups and businesses since 2017. We will advise you and propose the best solution.
Read also