虽然 Android 提供了各种 Widget 来提供小型、可重用、交互式元素,但您可能还需要重用需要特殊布局的较大组件。为了有效地重用完整布局,请使用 <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>
您还可以覆盖包含的布局的根视图的所有布局参数(任何 android:layout_*
属性),方法是在 <include>
标签中指定它们。这在以下示例中显示
<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>
标签有助于消除视图层次结构中冗余的视图组。 <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>
的更多信息,请参阅 布局资源。