使用 <include> 复用布局

虽然 Android 提供了各种小部件来提供小巧、可重复使用、交互式元素,但您可能还需要重复使用需要特殊布局的较大组件。为了有效地重复使用完整布局,请使用 <include><merge> 标签将一个布局嵌入另一个布局。

这使您能够创建复杂的布局,例如是或否按钮面板或带描述文本的自定义进度条。这意味着您可以提取应用程序中跨多个布局通用的任何元素,分别管理它们,并将它们包含在每个布局中。虽然您可以通过编写自定义 View 来创建单个 UI 组件,但您可以通过重复使用布局文件来更轻松地实现此目的。

创建可重复使用的布局

首先创建一个新的 XML 文件,并定义您想要重复使用的布局。例如,以下布局定义了一个标题栏,可以在每个活动中包含 (titlebar.xml)

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@color/titlebar_bg"
    tools:showIn="@layout/activity_main" >

    <ImageView android:layout_width="wrap_content"
               android:layout_height="wrap_content"
               android:src="@drawable/gafricalogo" />
</FrameLayout>

View 必须与您希望在要添加此布局的每个布局中显示的方式完全一致。

使用 <include> 标签

在要添加可重复使用组件的布局中,添加 <include> 标签。例如,以下布局包含了前面示例中的标题栏

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/app_bg"
    android:gravity="center_horizontal">

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

    <TextView android:layout_width="match_parent"
              android:layout_height="wrap_content"
              android:text="@string/hello"
              android:padding="10dp" />
    ...
</LinearLayout>

您还可以通过在 <include> 标签中指定它们来覆盖包含的布局的根视图的所有布局参数(任何 android:layout_* 属性)。这在以下示例中显示

<include android:id="@+id/news_title"
         android:layout_width="match_parent"
         android:layout_height="match_parent"
         layout="@layout/title"/>

但是,如果您想要使用 <include> 标签覆盖布局属性,还要覆盖 android:layout_heightandroid:layout_width,以使其他布局属性生效。

使用 <merge> 标签

当在一个布局中包含另一个布局时,<merge> 标签有助于消除视图层次结构中多余的视图组。<merge> 的一个用例是当您通过扩展 ViewGroup 来实现自定义视图时。

例如,如果您的主布局是一个垂直 LinearLayout,其中两个连续视图可以在多个布局中重复使用,那么放置这两个视图的可重复使用布局需要自己的根视图。但是,使用另一个 LinearLayout 作为可重复使用布局的根,会导致垂直 LinearLayout 位于垂直 LinearLayout 内部。嵌套的 LinearLayout 没有任何实际用途,并会降低 UI 性能。

相反,您可以扩展 LinearLayout 来创建一个自定义视图,并使用布局 XML 来描述其子视图。XML 中的顶部标签是 <merge>,而不是 LinearLayout,如以下示例所示

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

    <Button
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="@string/add"/>

    <Button
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="@string/delete"/>

</merge>

当您使用 <include> 标签将此布局包含在另一个布局中时,系统会忽略 <merge> 元素,并将两个按钮直接放置在布局中,以代替 <include> 标签。

有关 <include> 的更多信息,请参阅 布局资源