为什么对片段额外的FrameLayout产生的? [英] Why is an extra FrameLayout created for fragments?

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

问题描述

当使用层次观众以减少层级,我已经注意到,在每添加一个片段(无论是在静态和动态的方式)的片段总是包裹在一个新的FrameLayout

下面是一个例子:

这是我的活动的布局

 < RelativeLayout的的xmlns:机器人=htt​​p://schemas.android.com/apk/res/android
的xmlns:工具=htt​​p://schemas.android.com/tool​​s
机器人:layout_width =match_parent
机器人:layout_height =match_parent
机器人:contentDescription =mainActivityRoot>

<的TextView
    机器人:ID =@ + ID /参考hello world
    机器人:layout_width =match_parent
    机器人:layout_height =WRAP_CONTENT
    机器人:文本=@字符串/参考hello world/>

<片段
    机器人:名称=com.example.testfragments.MainFragment
    机器人:layout_width =match_parent
    机器人:layout_height =match_parent
    机器人:layout_below =@ ID /参考hello world/>

< / RelativeLayout的>
 

这是片段布局

 <进度机器人:ID =@ + ID / ProgressBar1的xmlns:机器人=htt​​p://schemas.android.com/apk/res/android
的xmlns:工具=htt​​p://schemas.android.com/tool​​s
机器人:layout_width =match_parent
机器人:contentDescription =mainFragmentRoot
机器人:layout_height =match_parent/>
 

活动源$ C ​​$ c是空的除了的setContentView , 和片段来源$ C ​​$ C仅包含

  @覆盖
公共查看onCreateView(...){
    返回inflater.inflate(R.layout.fragment_main,集装箱,假);
}
 

现在,

我希望看到的 PrograssBar 直接在活动根的层次,而是有一个额外的FrameLayout,我不知道它从何而来。 这里有一个屏幕截图,描绘了额外的帧黄光:

所以,我的问题是 - 它是在哪里来的呢?而且我可以摆脱它? 在我的实际应用中这些额外的FrameLayouts创建很深的层次结构这可能是坏的表现。

谢谢!

解决方案

好像你正在使用支持V4库,你忘了id为您的片段XML标签:),所以:

  

它是在哪里来的呢?

它来自<一个href="https://android.googlesource.com/platform/frameworks/support/+/master/v4/java/android/support/v4/app/FragmentManager.java#L888">line FragmentManager 888 中,你可以看到这一点:

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

这样做的原因是向后兼容性,这是更好的 NoSaveStateFrameLayout 的评论标题它说解释说:

  / **
 * pre-蜂窝版本的平台不具备{@link查看#setSaveFromParentEnabled(布尔)},
 *所以不是我们的观点与其父之间插入此。
 * /
 

  

我可以摆脱它?

嗯,我能想到的三个选项:

  1. 您可以有你自己的实施 FragmentManager 说,根据中省略了此容器支持V4库版本,但我觉得写的努力/维持了code是不值得的,再加上我不认为因为那些开销的FrameLayout s是巨大的,如果您有性能问题,你可能有其他的查看优化除此以外执行(比如写一个自定义视图华征信扩展视图 - ),或者说重新考虑你的布局/片段,以减少量视图层次结构中的某一点。
  2. 在等待支持V4库的新版本,其完成的 1 的&LT; - 是啊我是一个懒惰的人:D,你必须提交一个bug,如果没有一个已经(见的 3。的),这个凉爽的部分是,你甚至可以有助于你的补丁或其他人也是如此。
  3. 仅支持平台(或等待),其中支持V4库不(再)需要在API层面11+ FragmentManager 的实施不具有此嵌套<$ C C>的ViewGroup (见<一href="https://android.googlesource.com/platform/frameworks/base/+/refs/heads/master/core/java/android/app/FragmentManager.java#L861">line 11+ 861 FragmentManager ),对那些你得到这样的:

我不会担心太多对那些因为我提到有其他的优化​​,你可以投资的时间;)

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天全站免登陆