7

作为这个问题的后续,我想不出有什么好的理由不应该将每个包含的 XML 布局包装成一<merge>对。

这让我想知道,为什么 ADT 团队不将其设为默认行为?

有没有人不想要这种行为的情况?

顺便说一句,Android 文档中对<merge>标签的解释比最糟糕的法律协议中的措辞还要糟糕:

当在另一个布局中包含一个布局时,该<merge />标签有助于消除视图层次结构中的冗余视图组。例如,如果您的主布局是垂直LinearLayout的,其中两个连续的视图可以在多个布局中重复使用,那么放置两个视图的可重复使用的布局需要它自己的根视图。但是,使用另一个LinearLayout作为可重用布局的根会导致一个垂直LinearLayout内的一个垂直LinearLayout。嵌套LinearLayout除了降低您的 UI 性能之外没有任何实际用途。

罗曼,你在哪里?

4

1 回答 1

8

标签的主要目的include(我看到它的方式)是允许开发人员创建可重用的 xml 组件,以便在同一个活动或/和应用程序中的许多活动中多次使用。为了使该可重用组件真正有用,它需要是自包含的,并且尽可能减少外部连接。从我的角度来看,如果您要merge在每个包含的布局中使用标签,这将降低include标签的整体实用性。这是我认为会发生这种情况的一个例子:

考虑您想要实现一个可重用的ActionBarxml 组件以嵌入到您的每个活动中。它将包含水平放置的 aTextView和 a 。Button这样做的布局是:

R.layout.actionbar

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content" >

    <TextView
        android:id="@+id/actionbar_title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

    <Button
        android:id="@+id/actionbar_action"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

</LinearLayout>

现在假设您的应用程序中有两个活动,一个是根视图LinearLayout(方向垂直),另一个是根视图RelativeLayout。上面的布局可以很容易地包含在LinearLayout(只要把它放在你想要的地方),同样可以使用RelativeLayout,当然考虑到当前元素RelativeLayout(请记住,你必须设置layout_width/height(例如,复制从包含的布局的根)为include标签,以便layout_*考虑其他属性)。

现在考虑你的提议。布局将变为:

<merge xmlns:android="http://schemas.android.com/apk/res/android" >

    <TextView
        android:id="@+id/actionbar_title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

    <Button
        android:id="@+id/actionbar_action"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

</merge>

查看我们的ActionBar布局并不能告诉我们太多,您只需将 aTextView和 aButton包含在某处。现在考虑根是垂直方向的活动LinearLayoutR.layout.actionbar不能简单地包含布局,因为这会破坏我们的ActionBar,我们需要LinearLayout为我们的布局添加一个额外的(方向水平)以使其看起来符合要求。如您所见,您处于上述情况(没有merge标签的布局),但现在您必须记住将包含的布局包装在一个LinearLayout方向为水平的位置,而父根是一个LinearLayout方向为垂直的。

当根为 a 时,情况会变得更糟RelativeLayout,您不能简单地将include标签与mergea一起使用RelativeLayout(阅读如何让 RelativeLayout 与合并和包含一起工作的好问题?)。再次,选项是嵌入includeLinearLayout没有标签的情况下merge(但现在添加的问题比解决的问题更多)。还阅读此链接http://code.google.com/p/android/issues/detail?id=2863include的最后一部分可能会揭示该标签的其他错误。

从我上面的示例中可以看出,merge默认情况下使用标签可能会在某些情况下导致一些问题。此外,当前系统代表了一种更一致的布局方式(您可以为include标签创建布局,就像使用 root 创建普通布局一样View)。此外,merge标签是一种优化,我认为您不应该尝试优化,直到您开始看到一些性能问题(或者您真的想以复杂性为代价挤压每一次性能下降)。大多数应用程序在当前系统下都可以正常运行,具有大量视图的三四级深度布局可以在没有merge优化的情况下完全没有问题。

标签的另一个问题merge是,以膨胀为根的布局merge 需要在膨胀时将其自身附加到父级。如果要膨胀R.layout.actionbar布局,则必须将其附加到父级:

View actionBar = getLayoutInflater().inflate(R.layout.actionbar, root, true);

我不知道这是否是一个真正的限制,也许在某些罕见的情况下它可能会破坏交易。

只是我对include-merge对使用的看法。

于 2012-09-21T07:16:38.683 回答