虽然 Android 提供了各种微件来提供小型、可复用、交互式元素,但您可能还需要复用需要特殊布局的更大组件。为了高效复用完整布局,可以使用 <include> 和 <merge> 标签将一个布局嵌入到另一个布局中。
这使您可以创建复杂的布局,例如是/否按钮面板或带有描述文本的自定义进度条。这意味着您可以提取应用程序中在多个布局中通用的任何元素,单独管理它们,并将它们包含在每个布局中。虽然您可以通过编写自定义 View 来创建单独的 UI 组件,但通过复用布局文件可以更轻松地实现这一点。
创建可复用布局
首先创建一个新的 XML 文件并定义您想要复用的布局。例如,这是一个定义标题栏以便包含在每个 activity 中的布局 (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_* 属性)来覆盖被包含布局的根 View 的参数。如下例所示
<include android:id="@+id/news_title" android:layout_width="match_parent" android:layout_height="match_parent" layout="@layout/title"/>
但是,如果您想使用 <include> 标签覆盖布局属性,请同时覆盖 android:layout_height 和 android:layout_width,以使其他布局属性生效。
使用 <merge> 标签
<merge> 标签有助于在将一个布局包含到另一个布局中时,消除 View 层级中多余的 View Group。使用 <merge> 的一个用例是,当您通过扩展 ViewGroup 实现自定义 View 时。
例如,如果您的主布局是一个垂直的 LinearLayout,其中有两个连续的 View 可以在多个布局中复用,那么放置这两个 View 的可复用布局需要自己的根 View。然而,如果使用另一个 LinearLayout 作为可复用布局的根,将导致垂直 LinearLayout 嵌套在垂直 LinearLayout 内部。嵌套的 LinearLayout 没有实际作用,并会降低您的 UI 性能。
相反,您可以扩展 LinearLayout 以创建自定义 View,并使用布局 XML 来描述其子 View。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> 的更多信息,请参阅布局资源。