Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is an extra FrameLayout created for fragments?

While using the hierarchy viewer in order to reduce hierarchies, I've noticed that on each addition of a fragment (both in "static" or "dynamic" way) the fragments is always wrapped in a new FrameLayout.

Here's an example:

This is my activity layout:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:contentDescription="mainActivityRoot" >

<TextView
    android:id="@+id/hello_world"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:text="@string/hello_world" />

<fragment
    android:name="com.example.testfragments.MainFragment"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_below="@id/hello_world" />

</RelativeLayout>

And this is the fragment layout:

<ProgressBar android:id="@+id/ProgressBar1" xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:contentDescription="mainFragmentRoot"
android:layout_height="match_parent" />

The activity source code is empty besides the setContentView, And the fragment source code contains only

@Override
public View onCreateView(...) {
    return inflater.inflate(R.layout.fragment_main, container, false);
}

Now,

I would expect to see the PrograssBar directly in the hierarchy of the activity root, but instead there's an additional FrameLayout that I have no idea where it comes from. Here's a screen shot, painted the extra frame in YELLOW: Dump view hierarchy - yellow is bad

So, my questions is - where did it come from? and can I get rid of it? In my real application those extra FrameLayouts are creating very deep hierarchies which are probably bad for performance.

Thanks!

like image 723
Sean Avatar asked May 27 '13 13:05

Sean


People also ask

Why do we prefer FrameLayout for fragments?

Main purpose of frame layout is to block the area required to fit the largest child view. If you use a Frame Layout as Fragment Container you can ensure that you always have the space available to accommodate the largest fragment layout.

What's the purpose of FrameLayout?

FrameLayout is designed to block out an area on the screen to display a single item. Generally, FrameLayout should be used to hold a single child view, because it can be difficult to organize child views in a way that's scalable to different screen sizes without the children overlapping each other.

What is the difference between fragment and FrameLayout?

Show activity on this post. A framelayout, Relative View and a few others represents a view in android and is extended from viewgroup. A Fragment is a an an Object that is used to represent a portion of a user interface and is usually hosted in an activity. A fragment has a viewgroup which you can assign an XML layout.

Is FrameLayout a view?

Android Framelayout is a ViewGroup subclass that is used to specify the position of multiple views placed on top of each other to represent a single view screen. Generally, we can say FrameLayout simply blocks a particular area on the screen to display a single view.


1 Answers

It seems like you are using the support v4 library and you forgot to put and id to your fragment xml tag :), so:

where did it come from?

It comes from line 888 of FragmentManager where you can see this:

f.mView = NoSaveStateFrameLayout.wrap(f.mView);

The reason for this is backwards compatibility and it is better explained in the comment header of NoSaveStateFrameLayout which says:

/**
 * Pre-Honeycomb versions of the platform don't have {@link View#setSaveFromParentEnabled(boolean)},
 * so instead we insert this between the view and its parent.
 */

can I get rid of it?

Well, I can think of three options:

  1. You could have your very own implementation of FragmentManager say based on support v4 library version in which you omit this container, but I think the effort of writing/maintaining that code is not worth, plus I don't think the overhead due those FrameLayouts is gigantic, if you are having performance issues you probably have other View optimizations to perform besides this (say write a custom view -which extends View-) or say rethink your layout/fragments to reduce the amount of views in the hierarchy at certain point.
  2. Wait for a new release of support v4 library which accomplishes 1. <- yup I'm a lazy person :D, you'll have to file a bug if there is not one already (see 3.), the cool part of this is you could even contribute your patch or someone else as well.
  3. Support only platforms (or wait until) where the support v4 library is not (longer) needed, in API level 11+ FragmentManager implementation does not have this nested ViewGroup (see line 861 of 11+ FragmentManager), on those you get something like this:

Look mom!, no nested <code>FrameLayout</code>!!1

I wouldn't worry much for those as I mentioned there are other optimizations you can invest that time in ;)

like image 147
eveliotc Avatar answered Sep 18 '22 08:09

eveliotc