Android 安卓&x27的目的是什么;s<;合并>;XML布局中的标记?

Android 安卓&x27的目的是什么;s<;合并>;XML布局中的标记?,android,android-layout,include,code-reuse,Android,Android Layout,Include,Code Reuse,我已经阅读了标签,但我仍然不明白它有多有用。它是对标记的一种替换,还是这样使用: <merge xmlns:android="...."> <LinearLayout ...> . . . </LinearLayout> </merge> . . . 然后,另一个文件中的代码是有用的,因为它可以消除不必要的视图组,即仅用于包装其他视图而本身没有任何用途的布局 例如,如果要从另一个文件中布局而不使用“合并”,则这两个文件

我已经阅读了
标签,但我仍然不明白它有多有用。它是对
标记的一种替换,还是这样使用:

<merge xmlns:android="....">
<LinearLayout ...>
    .
    .
    .
</LinearLayout>
</merge>

.
.
.
然后,另一个文件中的代码是有用的,因为它可以消除不必要的视图组,即仅用于包装其他视图而本身没有任何用途的布局

例如,如果要从另一个文件中
布局而不使用“合并”,则这两个文件的外观可能如下所示:

layout1.xml:

<FrameLayout>
   <include layout="@layout/layout2"/>
</FrameLayout>

layout2.xml:

<FrameLayout>
   <TextView />
   <TextView />
</FrameLayout>
<merge>
   <TextView />
   <TextView />
</merge>

其功能等同于此单一布局:

<FrameLayout>
   <FrameLayout>
      <TextView />
      <TextView />
   </FrameLayout>
</FrameLayout>

layout2.xml中的FrameLayout可能没有用处<代码>有助于摆脱它。下面是使用merge时的情况(layout1.xml不变):

layout2.xml:

<FrameLayout>
   <TextView />
   <TextView />
</FrameLayout>
<merge>
   <TextView />
   <TextView />
</merge>

这在功能上等同于此布局:

<FrameLayout>
   <TextView />
   <TextView />
</FrameLayout>


但是由于您使用的是
,因此可以在其他地方重用布局。它不必仅用于替换框架布局-您可以使用它来替换任何没有为视图的外观/行为添加有用内容的布局。

blazeroni已经非常清楚了,我只想补充几点

  • 用于优化布局。用于减少不必要的嵌套
  • 将包含
    标记的布局添加到另一个布局中时,将删除
    节点,并将其子视图直接添加到新的父视图中
包含标签 标签允许您将布局划分为多个文件:它有助于处理复杂或过长的用户界面

假设使用两个包含文件拆分复杂布局,如下所示:

顶级活动.xml

。。。和include2.xml

<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/textView1"
    android:text="First include"
    android:textAppearance="?android:attr/textAppearanceMedium"/>
<?xml version="1.0" encoding="utf-8"?>
<Button xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/button1"
    android:text="Button" />
在java代码中,所有这些都是透明的:
findviewbyd(R.id.textView1)
在活动类中返回正确的小部件(即使该小部件是在与活动布局不同的xml文件中声明的)

上面的樱桃:可视化编辑器处理起来很顺利。顶层布局呈现时包含xml

情节越来越复杂 由于包含文件是一个典型的布局xml文件,这意味着它必须有一个顶层元素。 因此,如果您的文件需要包含多个小部件,则必须使用布局

假设
include1.xml
现在有两个
TextView
:必须声明布局。让我们选择一个
线性布局

include1.xml

现在,顶级活动.xml呈现为:


您保存了一个层次结构级别,避免了一个无用的视图:Romain Guy已经睡得更好了


您现在不是更开心了吗?

使用合并的另一个原因是在ListView或GridView中使用自定义视图组时。您可以使用自定义视图,而不是在列表适配器中使用viewHolder模式。自定义视图将膨胀根为合并标记的xml。 适配器的代码:

public class GridViewAdapter extends BaseAdapter {
     // ... typical Adapter class methods
     @Override
     public View getView(int position, View convertView, ViewGroup parent) {
        WallpaperView wallpaperView;
        if (convertView == null)
           wallpaperView = new WallpaperView(activity);
        else
            wallpaperView = (WallpaperView) convertView;

        wallpaperView.loadWallpaper(wallpapers.get(position), imageWidth);
        return wallpaperView;
    }
}
以下是自定义视图组:

public class WallpaperView extends RelativeLayout {

    public WallpaperView(Context context) {
        super(context);
        init(context);
    }
    // ... typical constructors

    private void init(Context context) {
        View.inflate(context, R.layout.wallpaper_item, this);
        imageLoader = AppController.getInstance().getImageLoader();
        imagePlaceHolder = (ImageView) findViewById(R.id.imgLoader2);
        thumbnail = (NetworkImageView) findViewById(R.id.thumbnail2);
        thumbnail.setScaleType(ImageView.ScaleType.CENTER_CROP);
    }

    public void loadWallpaper(Wallpaper wallpaper, int imageWidth) {
        // ...some logic that sets the views
    }
}
下面是XML:

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

    <ImageView
        android:id="@+id/imgLoader"
        android:layout_width="30dp"
        android:layout_height="30dp"
        android:layout_centerInParent="true"
        android:src="@drawable/ico_loader" />

    <com.android.volley.toolbox.NetworkImageView
        android:id="@+id/thumbnail"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

</merge>

为了更深入地了解正在发生的事情,我创建了以下示例。查看activity_main.xml和content_profile.xml文件

activity_main.xml


content_profile.xml


在这里,充气时整个布局文件如下所示

<LinearLayout>
    <LinearLayout>
        <TextView />
        <TextView />
    </LinearLayout>
</LinearLayout>

请注意,在父LinearLayout中有一个LinearLayout,它不起任何作用,并且是冗余的。通过布局检查器工具查看布局可以清楚地解释这一点

更新代码后,content_profile.xml将使用merge而不是像LinearLayout这样的视图组

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

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Howdy" />

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Hi there" />

</merge>

现在我们的布局是这样的

<LinearLayout>
    <TextView />
    <TextView />
</LinearLayout>

在这里,我们看到冗余的LinearLayout视图组被删除。现在,布局检查器工具提供了以下布局层次结构


因此,当父布局可以定位子布局时,请始终尝试使用“合并”,或者更准确地说,当您了解层次结构中将存在冗余视图组时,请使用“合并”。

在本例中,您可以使layout2.xml仅包含
,而不包含其他内容。为,在layout2中可以使用一个简单的文本视图,但是这将是一个完全不同的事情,并且在回答这个问题时,作为一个例子是没有用的。与标记一起使用时,使用标记总是有用的。@Karu:你是对的,本例中不需要merge标记,但这只是因为layout2中有一个元素。如果layout2有多个元素,那么它必须有一个根节点才能成为有效的XML,这时合并标记就派上了用场?你如何给出布局权重?非常好的描述。解释得非常清楚,应该被选为答案。非常好,毫无疑问,这应该是公认的答案。我不懂一些东西。。例如,如果外部LinearLayout是垂直的,但是include1.xml中的两个文本视图应该是水平的,该怎么办?这种情况下的合并不会保存我想要的布局。怎么办?@YonatanNir merge显然不是你需要的。如果确实需要展平视图层次结构,那么也许可以使用
RelativeLayout
或手动绘制视图。这是否意味着,如果在XML文件中使用RelativeLayout,并且自定义视图组继承自RelativeLayout,那么将有两个RelativeLayout,一个嵌套在另一个中?
<merge xmlns:android="http://schemas.android.com/apk/res/android">

    <ImageView
        android:id="@+id/imgLoader"
        android:layout_width="30dp"
        android:layout_height="30dp"
        android:layout_centerInParent="true"
        android:src="@drawable/ico_loader" />

    <com.android.volley.toolbox.NetworkImageView
        android:id="@+id/thumbnail"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

</merge>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <include layout="@layout/content_profile" />

</LinearLayout>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Howdy" />

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Hi there" />

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

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Howdy" />

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Hi there" />

</merge>
<LinearLayout>
    <TextView />
    <TextView />
</LinearLayout>