虽然 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>
的更多信息,请参阅布局资源。