为什么要为片段创建一个额外的 FrameLayout? [英] Why is an extra FrameLayout created for fragments?
问题描述
在使用 ,您可以在其中看到:
f.mView = NoSaveStateFrameLayout.wrap(f.mView);
这样做的原因是向后兼容,并且在 NoSaveStateFrameLayout
的注释标题中有更好的解释,它说:
/*** 平台的 Pre-Honeycomb 版本没有 {@link View#setSaveFromParentEnabled(boolean)},* 所以我们在视图和它的父视图之间插入这个.*/
<块引用>
我可以摆脱它吗?
嗯,我能想到三个选项:
- 你可以有你自己的
FragmentManager
实现,比如你省略了这个容器的支持 v4 库版本,但我认为编写/维护该代码的努力是不值得的,而且我不要认为那些FrameLayout
的开销很大,如果您遇到性能问题,除此之外,您可能还有其他View
优化要执行(比如编写自定义视图 -extends View
-) 或者说重新考虑您的布局/片段以减少特定点层次结构中的视图数量. - 等待新版本的支持 v4 库完成1. <- 是的,我是个懒人 :D,如果还没有错误,您必须提交错误(请参阅3.),其中很酷的部分是您甚至可以贡献您的补丁或其他人.
- 仅支持不需要(不再)支持 v4 库的平台(或等到),在 API 级别 11+
FragmentManager
实现中没有这个嵌套的ViewGroup
(参见 11+FragmentManager
的第 861 行),你会得到这样的结果:
我不会为那些担心太多,因为我提到过您可以花时间进行其他优化;)
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:
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!
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:
- 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 thoseFrameLayout
s is gigantic, if you are having performance issues you probably have otherView
optimizations to perform besides this (say write a custom view -whichextends View
-) or say rethink your layout/fragments to reduce the amount of views in the hierarchy at certain point. - 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.
- 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 nestedViewGroup
(see line 861 of 11+FragmentManager
), on those you get something like this:
I wouldn't worry much for those as I mentioned there are other optimizations you can invest that time in ;)
这篇关于为什么要为片段创建一个额外的 FrameLayout?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!