为什么要为片段创建一个额外的 FrameLayout? [英] Why is an extra FrameLayout created for fragments?

查看:21
本文介绍了为什么要为片段创建一个额外的 FrameLayout?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在使用 ,您可以在其中看到:

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

这样做的原因是向后兼容,并且在 NoSaveStateFrameLayout 的注释标题中有更好的解释,它说:

/*** 平台的 Pre-Honeycomb 版本没有 {@link View#setSaveFromParentEnabled(boolean)},* 所以我们在视图和它的父视图之间插入这个.*/

<块引用>

我可以摆脱它吗?

嗯,我能想到三个选项:

  1. 你可以有你自己的 FragmentManager 实现,比如你省略了这个容器的支持 v4 库版本,但我认为编写/维护该代码的努力是不值得的,而且我不要认为那些 FrameLayout 的开销很大,如果您遇到性能问题,除此之外,您可能还有其他 View 优化要执行(比如编写自定义视图 -extends View-) 或者说重新考虑您的布局/片段以减少特定点层次结构中的视图数量.
  2. 等待新版本的支持 v4 库完成1. <- 是的,我是个懒人 :D,如果还没有错误,您必须提交错误(请参阅3.),其中很酷的部分是您甚至可以贡献您的补丁或其他人.
  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:

  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:

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

这篇关于为什么要为片段创建一个额外的 FrameLayout?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆