尽管 Android 通过各种 widget 来提供可重复使用的小型互动元素,但您可能还需要重复使用需要特殊布局的大型组件。为了高效地重复使用完整的布局,请使用 <include>
和 <merge>
标记将一个布局嵌入到另一个布局中。
这样,您就可以创建复杂的布局,例如“是/否”按钮面板或包含说明文本的自定义进度条。这意味着,您可以提取应用中多个布局中通用的任何元素,单独管理这些元素,并将其添加到各个布局中。尽管您可以通过编写自定义 View
来创建各个界面组件,但也可以通过重复使用布局文件来更加轻松地达成目标。
创建可重复使用的布局
首先,创建一个新的 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_*
属性)进行替换。具体可见以下示例:
<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
没有任何实际用途,还会降低界面性能。
不过,您可以扩展 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>
,请参阅布局资源。