Search code examples
androidandroid-layoutandroid-linearlayoutandroid-relativelayoutandroid-framelayout

Why does LinearLayout not correctly display nested FrameLayout?


I have an XML layout where I nested a FrameLayout within a LinearLayout and attempted to stack a sibling viewing group on top of the FrameLayout. It does not show the sibling viewing group at all, but just the FrameLayout. I wanted to please get some help in understanding why replacing the root ViewGroup to a RelativeLayout produces an expected output.

Here is the Layout:

<?xml version="1.0" encoding="utf-8"?>  
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
     android:orientation="vertical">
     <FrameLayout  
         android:layout_width="match_parent"  
         android:layout_height="match_parent"
         android:id="@+id/mainFrameLayout"
         android:background="#787878"/>
    <LinearLayout
         android:layout_width="match_parent"
         android:layout_height="match_parent"
         android:orientation="vertical">  
         <ImageView  
             android:id="@+id/ImageView01"  
             android:layout_height="wrap_content"  
             android:layout_width="match_parent"  
             android:src="@drawable/download"  
             android:adjustViewBounds="true"/>
         <TextView  
             android:layout_width="match_parent"  
             android:layout_height="wrap_content"  
             android:textColor="#000"  
             android:textSize="40sp"  
             android:text="Top text" />
         <TextView
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
             android:layout_gravity="bottom"
             android:gravity="right"
             android:text="bottom_text"
             android:textColor="#fff"
             android:textSize="50sp" />
</LinearLayout>

</LinearLayout>

I only see the FrameLayout by itself filling the screen. When I change the root ViewGroup to a RelativeLayout defined with a layout_height and layout_width to "match_parent", I get my expected output where the ImageView and both TextViews show on top of the FrameLayout. I am confused on how that made it work because I didn't specify any RelativeLayout parameters to the child ViewGroups/View like "bottomof" or "topof".

Is there a resizing propery or weight distribution that RelativeLayout has that LinearLayout does not? I have been looking online, but unfortunately have not found an answer.

Thank you!


Solution

  • In the code you showed, the first FrameLayout matches the parent's height, so the LinearLayout that follows is pushed offscreen below (y-axis, not z-axis) the FrameLayout. This is because their parent is a LinearLayout, which arranges it's children one below the other vertically (y-axis), non-overlaping (as in a roll of toiler paper where each view is a paper square).

    If you wanted the child FrameLayout and LinearLayout to be on top of the other (z-axis) their parent would have to be a FrameLayout, which arranges it's children one on top of the other overlaping in the z-axis (as in a stack of paper sheets).

    As to why a RelativeLayout without specifying layout parameters gave you your expected behavior, it's because the default is to place child views at the top left corner of the container (from RelativeLayout documentation):

    By default, all child views are drawn at the top-left of the layout, so you must define the position of each view using the various layout properties available from RelativeLayout.LayoutParams.