<include> でレイアウトを再利用する

Android ではさまざまなウィジェットが用意されており、小型で再利用できるインタラクティブな要素を提供していますが、特別なレイアウトが必要な大規模コンポーネントの再利用が必要となる場合もあります。完全なレイアウトを効率的に再利用するには、<include> タグと <merge> タグを使用して、1 つのレイアウトを別のレイアウト内に埋め込みます。

これにより、「はい / いいえ」ボタンパネルや、説明テキスト付きのカスタム進行状況バーなど、複雑なレイアウトを作成できます。つまり、複数のレイアウトに共通するアプリの要素を抽出して個別に管理し、各レイアウトに含めることができます。カスタム 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_heightandroid:layout_width もオーバーライドして、他のレイアウト属性を有効にします。

<merge> タグを使用する

<merge> タグを使用すると、1 つのレイアウトを別のレイアウトに含める際に、ビュー階層内の冗長なビューグループを削除できます。<merge> のユースケースの 1 つは、ViewGroup を拡張してカスタムビューを実装する場合です。

たとえば、メイン レイアウトが、2 つの連続するビューを複数のレイアウトで再利用できる縦向きの LinearLayout である場合、2 つのビューを配置する再利用可能なレイアウトには独自のルートビューが必要です。ただし、再利用可能なレイアウトのルートとして別の LinearLayout を使用すると、縦長の LinearLayout 内に縦長の LinearLayout が作成されます。LinearLayout のネストは実用性がなく、UI のパフォーマンスが低下します。

代わりに、LinearLayout を拡張してカスタムビューを作成し、レイアウト XML を使用してその子ビューを記述できます。次の例に示すように、XML の一番上のタグは LinearLayout ではなく <merge> です。

<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> タグの代わりに 2 つのボタンがレイアウト内に直接配置されます。

<include> の詳細については、レイアウト リソースをご覧ください。