Хотя Android предлагает множество виджетов для создания небольших интерактивных элементов многократного использования, вам также может потребоваться повторно использовать более крупные компоненты, требующие специального макета. Чтобы эффективно повторно использовать полные макеты, используйте теги <include>
и <merge>
для встраивания одного макета в другой.
Это позволяет создавать сложные макеты, например панель кнопок «да» или «нет» или пользовательский индикатор выполнения с текстом описания. А это значит, что вы можете извлекать любые элементы вашего приложения, общие для нескольких макетов, управлять ими отдельно и включать их в каждый макет. Хотя вы можете создавать отдельные компоненты пользовательского интерфейса, написав собственный View
, вы можете сделать это проще, повторно используя файл макета.
Создайте повторно используемый макет
Начните с создания нового 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
не имеет никакой реальной цели и снижает производительность пользовательского интерфейса.
Вместо этого вы можете расширить 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>
см. в разделе Ресурс макета .