android - 为什么我们不应该将每个包含的 Android XML 布局包装在一个 <merge> 对中?

标签 android android-layout include code-reuse

作为此 question 的后续行动,我想不出任何不应该将每个包含的 XML 布局包装在 <merge> 中的充分理由。一对。

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

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

顺便提一下Android documentation中的解释的<merge> tag 比最糟糕的法律协议(protocol)中的措辞更糟糕:

The <merge /> tag helps eliminate redundant view groups in your view hierarchy when including one layout within another. For example, if your main layout is a vertical LinearLayout in which two consecutive views can be re-used in multiple layouts, then the re-usable layout in which you place the two views requires its own root view. However, using another LinearLayout as the root for the re-usable layout would result in a vertical LinearLayout inside a vertical LinearLayout. The nested LinearLayout serves no real purpose other than to slow down your UI performance.



罗曼,你在哪里?

最佳答案

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

考虑你想实现一个可重用的 ActionBar xml 组件嵌入到您的每个 Activity 中。它将包含 TextViewButton水平放置。这样做的布局是:

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>

现在假设您的应用程序中有两个 Activity ,其中一个 Root View 是 LinearLayout (方向垂直)和一个 Root View 是 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布局并没有告诉我们太多,你只有一个 TextViewButton被包括在某处。现在考虑根是垂直方向的 Activity LinearLayout .版面R.layout.actionbar不能简单地包括在内,因为这会破坏我们的 ActionBar ,我们需要添加一个额外的LinearLayout (方向水平)为我们的布局,使其看起来如所希望的。如您所见,您处于上述情况(没有 merge 标签的布局),但现在您必须记住将包含的布局包装在 LinearLayout 中在父根为 LinearLayout 的位置水平方向方向垂直。

当根是 RelativeLayout 时,情况会变得更糟。 , 你不能简单地使用 include带有 merge 的标签在 RelativeLayout (阅读 How to get RelativeLayout working with merge and include? 的好问题)。再次,选项是嵌入 includeLinearLayout这使您处于没有 merge 的情况下标记(但现在添加的问题比解决的问题更多)。还阅读此链接的最后一部分 http://code.google.com/p/android/issues/detail?id=2863 include 可能会揭示其他错误标签。

从我上面的例子可以看出,拥有 merge默认情况下,标签在某些情况下可能会导致一些问题。此外,当前系统代表了一种更一致的布局方式(您可以为 include 标签创建布局,就像创建带有根 View 的普通布局一样)。此外,merge标签是一种优化,我认为您不应该尝试优化,直到您开始看到一些性能问题(或者您真的想以复杂性为代价挤压每一滴性能)。大多数应用程序在当前系统下都可以正常运行,没有 merge 的具有相当数量 View 的三四级深度布局可以生存。优化完全没有问题。
merge 的另一个问题标签是具有 merge 的膨胀布局因为它的根需要在膨胀时将自己连接到父级。如果你要给 R.layout.actionbar 充气布局,那么您必须将其附加到父级:
View actionBar = getLayoutInflater().inflate(R.layout.actionbar, root, true);

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

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

关于android - 为什么我们不应该将每个包含的 Android XML 布局包装在一个 <merge> 对中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12518446/

相关文章:

java - 在警报对话框中,我想显示所选值

Eclipse 未检测到 HTC 渴望作为设备

java - 由 Alarm Manager 触发的 Pending Intent 似乎会立即触发

android-layout - 我的 WebView 没有填充选项卡的屏幕(但没有 pb 填充手机的屏幕)

android - 具有不同状态图像大小的 ImageButton

java - 使用 Maven Jaxb 编译时如何在目标 Jar 文件中包含 Xml 模式/资源?

c++ - 检查包含的库 C++ 的大小

android - 如何处理 SearchView 中的后退箭头事件

Android 布局方向未在运行时语言更改时更新

c++ - siginfo_t 尚未声明 : caused by inclusion of a thrift header