【问题标题】:Why is an extra FrameLayout created for fragments?为什么要为片段创建额外的 FrameLayout?
【发布时间】:2013-05-27 13:55:36
【问题描述】:

虽然使用hierarchy viewer 来减少层次结构,但我注意到在每次添加片段时(以“静态”或“动态”方式),片段总是包裹在 新的 FrameLayout

这是一个例子:

这是我的活动布局

<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>

这是片段布局

<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" />

活动源代码除setContentView外为空, 而片段源代码只包含

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

现在,

我希望直接在活动根的层次结构中看到PrograssBar,但是有一个额外的 FrameLayout,我不知道它来自哪里。 这是一个屏幕截图,用黄色绘制了额外的框架:

所以,我的问题是 - 它是从哪里来的?我可以摆脱它吗? 在我的实际应用程序中,那些额外的 FrameLayout 会创建非常深的层次结构,这可能对性能不利。

谢谢!

【问题讨论】:

    标签: android performance view android-fragments


    【解决方案1】:

    您似乎正在使用支持 v4 库,而您忘记将和 id 放入片段 xml 标记:),所以:

    它是从哪里来的?

    它来自line 888 of FragmentManager,你可以在这里看到:

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

    这样做的原因是向后兼容,在NoSaveStateFrameLayout 的评论标题中可以更好地解释:

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

    我可以摆脱它吗?

    嗯,我可以想到三个选项:

    1. 您可以拥有自己的 FragmentManager 实现,例如基于支持 v4 库版本,在其中省略此容器,但我认为编写/维护该代码的努力是不值得的,而且我不认为由于那些FrameLayouts 的开销是巨大的,如果您遇到性能问题,您可能还有其他View 优化要执行除此之外(例如编写自定义视图-extends View-)或者说重新考虑您的布局/片段以减少层次结构中特定点的视图数量。
    2. 等待支持 v4 库的新版本完成1. 3.),其中很酷的部分是您甚至可以贡献您的补丁或其他人。
    3. 仅支持不需要(更长)支持 v4 库的平台(或等到),在 API 级别 11+ FragmentManager 实现中没有此嵌套 ViewGroup(请参阅 line 861 of 11+ FragmentManager),在那些你得到这样的东西:

    我不会太担心那些,因为我提到了你可以花时间在其他优化上;)

    【讨论】:

    • 你先生 - 摇滚!非常感谢您的全面回答。
    • 我为此打开了一个问题:code.google.com/p/android/issues/…
    • 有没有办法获取Fragment添加的FrameLayout?我想将其 clipChildren 设置为 false,因为它正在剪裁其子视图。
    猜你喜欢
    • 2013-07-03
    • 2018-06-10
    • 2018-05-15
    • 2012-09-16
    • 1970-01-01
    • 1970-01-01
    • 2012-08-13
    • 1970-01-01
    • 2014-03-26
    相关资源
    最近更新 更多