include 标签的主要目的(我认为)是允许开发人员创建可重用的 xml 组件,以便在同一个活动或/和应用程序中的许多活动中多次使用。为了使该可重用组件真正有用,它需要是自包含的,并且尽可能减少外部连接。从我的角度来看,如果您要在每个包含的布局中使用 merge 标签,这将降低 include 标签的整体实用性。这是我认为会发生这种情况的一个例子:
考虑您想要实现一个可重用的ActionBar xml 组件以嵌入到您的每个活动中。它将包含一个TextView 和一个水平放置的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 中的当前元素(请记住您必须为include 标记设置layout_width/height(例如,从包含的布局的根目录复制),以便考虑其他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 布局并不能告诉我们太多,您只需在某处包含TextView 和Button。现在考虑根是垂直方向LinearLayout 的活动。布局R.layout.actionbar 不能简单地包含,因为这会破坏我们的ActionBar,我们需要为我们的布局添加一个额外的LinearLayout(方向为水平)以使其看起来符合需要。如您所见,您处于上述情况(没有merge 标签的布局),但是现在您必须记住将包含的布局包装在具有水平方向的LinearLayout 中,只要父根是LinearLayout方向垂直。
当根是RelativeLayout 时,情况会变得更糟,您不能简单地将include 标记与merge 一起用于RelativeLayout(阅读How to get RelativeLayout working with merge and include? 的好问题)。再次,选项是将include 嵌入到LinearLayout 中,这会使您处于没有merge 标记的情况(但现在添加的问题多于解决问题)。阅读此链接的最后一部分http://code.google.com/p/android/issues/detail?id=2863 可能会发现带有include 标签的其他错误。
从我上面的示例中可以看出,默认情况下使用merge 标签可能会在某些情况下导致一些问题。此外,当前系统代表了一种更一致的布局方式(您可以为 include 标签创建布局,就像使用根 View 创建普通布局一样)。此外,merge 标签是一种优化,我认为您不应该尝试优化,直到您开始看到一些性能问题(或者您真的想以复杂性为代价挤压每一次性能下降)。大多数应用程序在当前系统下都可以正常运行,具有相当数量视图的三四级深度布局可以在没有merge 优化的情况下完全没有问题。
merge 标签的另一个问题是,以merge 作为其根的膨胀布局需要在膨胀时将自身附加到父级。如果您要膨胀 R.layout.actionbar 布局,则必须将其附加到父级:
View actionBar = getLayoutInflater().inflate(R.layout.actionbar, root, true);
我不知道这是否是一个真正的限制,也许在极少数情况下它可能会破坏交易。
我对@987654367@ - merge 对使用的看法。