Intereting Posts
Платформы Android SDK между Linux и Windows Студия Android: как принудительно переустановить (отключить мгновенный запуск за один раз)? Android проверяет статус WIFI (отключен или пользователь изменен WIFI) Как FLAG это? Использование SurfaceTexture в сочетании с RenderScript Неожиданные результаты, реализующие простое размытие движения в Libgdx Понимание многопользовательских экранов поддержки Почему я могу успешно перенести файл в Linux во время его написания? GetSupportActionBar изнутри фрагмента ActionBarCompat Изменение позиции меню панели действий в Android Изменение размера изображения JPEG в файловой системе Outer Recyclerview не получает события прокрутки внутреннего Recyclerview Ошибка ресурса в студии android после обновления: не найден ресурс Как сервис возвращает результат активности Существуют ли какие-либо рекомендации для значений кодов запросов в Android? Ошибка: compileSdkVersion android-21 требует компиляции с JDK 7

Какова цель тега Android <merge> в XML-макетах?

Я прочитал сообщение Ромена Гая в <merge /> , но я до сих пор не понимаю, как он полезен. Является ли это заменой <Frame /> или используется так:

 <merge xmlns:android="...."> <LinearLayout ...> . . . </LinearLayout> </merge> 

Затем <include /> код в другом файле?

Solutions Collecting From Web of "Какова цель тега Android <merge> в XML-макетах?"

<merge/> полезен, потому что он может избавиться от ненужных ViewGroups, то есть макетов, которые просто используются для обертывания других представлений и сами не служат цели.

Например, если вы были <include/> макет из другого файла без использования слияния, два файла могли бы выглядеть примерно так:

layout1.xml:

 <FrameLayout> <include layout="@layout/layout2"/> </FrameLayout> 

layout2.xml:

 <FrameLayout> <TextView /> </FrameLayout> 

Который функционально эквивалентен этому единственному макету:

 <FrameLayout> <FrameLayout> <TextView /> </FrameLayout> </FrameLayout> 

Этот FrameLayout в layout2.xml может оказаться непригодным. <merge/> помогает избавиться от него. Вот как это выглядит с помощью merge (layout1.xml не изменяется):

layout2.xml:

 <merge> <TextView /> </merge> 

Это функционально эквивалентно этой схеме:

 <FrameLayout> <TextView /> </FrameLayout> 

Но поскольку вы используете <include/> вы можете повторно использовать макет в другом месте. Он не должен использоваться для замены только FrameLayouts – вы можете использовать его для замены любого макета, который не добавляет ничего полезного в то, как выглядит ваш взгляд.

Тег include

Тег <include> позволяет разделить макет на несколько файлов: он помогает работать с сложным пользовательским интерфейсом.

Предположим, вы разделили сложный макет с помощью двух включенных файлов следующим образом:

Top_level_activity.xml :

 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/layout1" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <!-- First include file --> <include layout="@layout/include1.xml" /> <!-- Second include file --> <include layout="@layout/include2.xml" /> </LinearLayout> 

Затем вам нужно написать include1.xml и include2.xml .

Имейте в виду, что xml из top_level_activity файлов просто top_level_activity макете top_level_activity во время рендеринга (почти так же, как макрос #INCLUDE для C).

Файлы include – это простой jane layout xml.

Include1.xml :

 <?xml version="1.0" encoding="utf-8"?> <TextView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/textView1" android:text="First include" android:textAppearance="?android:attr/textAppearanceMedium"/> 

… и include2.xml :

 <?xml version="1.0" encoding="utf-8"?> <Button xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/button1" android:text="Button" /> 

Видеть? Ничего особенного. Обратите внимание, что вам все равно нужно объявить пространство имен android с помощью xmlns:android="http://schemas.android.com/apk/res/android .

Таким образом, рендеринговая версия top_level_activity.xml :

 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/layout1" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <!-- First include file --> <TextView android:id="@+id/textView1" android:text="First include" android:textAppearance="?android:attr/textAppearanceMedium"/> <!-- Second include file --> <Button android:id="@+id/button1" android:text="Button" /> </LinearLayout> 

В вашем Java-коде все это прозрачно: findViewById(R.id.textView1) в вашем классе активности возвращает правильный виджет (даже если этот виджет был объявлен в XML-файле, отличном от макета активности).

И вишня сверху: визуальный редактор обрабатывает вещь плавно. Макет верхнего уровня визуализируется с включенным xml.

Сюжет загустеет

Поскольку файл include представляет собой классический XML-файл макета, это означает, что он должен иметь один верхний элемент. Поэтому, если ваш файл должен содержать более одного виджета, вам придется использовать макет.

Предположим, что include1.xml теперь имеет два TextView : должен быть объявлен макет. Выберем LinearLayout .

Include1.xml :

 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/layout2" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <TextView android:id="@+id/textView1" android:text="Second include" android:textAppearance="?android:attr/textAppearanceMedium"/> <TextView android:id="@+id/textView2" android:text="More text" android:textAppearance="?android:attr/textAppearanceMedium"/> </LinearLayout> 

Top_level_activity.xml будет отображаться как:

 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/layout1" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <!-- First include file --> <LinearLayout android:id="@+id/layout2" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <TextView android:id="@+id/textView1" android:text="Second include" android:textAppearance="?android:attr/textAppearanceMedium"/> <TextView android:id="@+id/textView2" android:text="More text" android:textAppearance="?android:attr/textAppearanceMedium"/> </LinearLayout> <!-- Second include file --> <Button android:id="@+id/button1" android:text="Button" /> </LinearLayout> 

Но подождите, пока два уровня LinearLayout будут лишними !

Действительно, два вложенных LinearLayout не LinearLayout никакой цели, поскольку два TextView могут быть включены в layout1 для точно такой же рендеринга .

Так что мы можем сделать?

Введите тег слияния

Тег <merge> – это только фиктивный тег, который предоставляет элемент верхнего уровня для решения таких проблем с избыточным кодом.

Теперь include1.xml становится:

 <merge xmlns:android="http://schemas.android.com/apk/res/android"> <TextView android:id="@+id/textView1" android:text="Second include" android:textAppearance="?android:attr/textAppearanceMedium"/> <TextView android:id="@+id/textView2" android:text="More text" android:textAppearance="?android:attr/textAppearanceMedium"/> </merge> 

И теперь top_level_activity.xml отображается как:

 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/layout1" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <!-- First include file --> <TextView android:id="@+id/textView1" android:text="Second include" android:textAppearance="?android:attr/textAppearanceMedium"/> <TextView android:id="@+id/textView2" android:text="More text" android:textAppearance="?android:attr/textAppearanceMedium"/> <!-- Second include file --> <Button android:id="@+id/button1" android:text="Button" /> </LinearLayout> 

Вы сохранили один уровень иерархии, избегайте бесполезного взгляда: Ромен Гай уже лучше спит.

Разве вы не счастливы сейчас?

В простых и точных словах,

Когда макет, содержащий тег merge, добавляется в другой макет, узел объединения удаляется, а его дочерние представления добавляются непосредственно к новому родительскому элементу.

Тег merge особенно полезен в сочетании с include tag , который используется для вставки содержимого одного макета в другой.

пример

 <?xml version=”1.0” encoding=”utf-8”?> <LinearLayout xmlns:android=”http://schemas.android.com/apk/res/android” android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <include android:id="@+id/my_id1" layout="@layout/layout1"/> <include android:id="@+id/my_id2" layout="@layout/layout2"/> </LinearLayout> 

Blazeroni уже делает это довольно ясно, я просто хочу добавить несколько очков.

  • <merge> Merge <merge> используется для оптимизации layouts.It используется для уменьшения ненужной вложенности.
  • Когда макет, содержащий тэг <merge> добавляется в другой макет, узел <merge> удаляется и его дочерний вид добавляется непосредственно к новому родительскому элементу.
  • Тег <merge> особенно полезен при использовании <include> который используется для вставки содержимого другого макета.

Другой причиной использования слияния является использование пользовательских групп просмотра в ListViews или GridViews. Вместо использования шаблона viewHolder в адаптере списка вы можете использовать пользовательский вид. Пользовательское представление будет раздувать xml, корень которого является тегом слияния. Код для адаптера:

 public class GridViewAdapter extends BaseAdapter { // ... typical Adapter class methods @Override public View getView(int position, View convertView, ViewGroup parent) { WallpaperView wallpaperView; if (convertView == null) wallpaperView = new WallpaperView(activity); else wallpaperView = (WallpaperView) convertView; wallpaperView.loadWallpaper(wallpapers.get(position), imageWidth); return wallpaperView; } } 

Вот пользовательская группа просмотра:

 public class WallpaperView extends RelativeLayout { public WallpaperView(Context context) { super(context); init(context); } // ... typical constructors private void init(Context context) { View.inflate(context, R.layout.wallpaper_item, this); imageLoader = AppController.getInstance().getImageLoader(); imagePlaceHolder = (ImageView) findViewById(R.id.imgLoader2); thumbnail = (NetworkImageView) findViewById(R.id.thumbnail2); thumbnail.setScaleType(ImageView.ScaleType.CENTER_CROP); } public void loadWallpaper(Wallpaper wallpaper, int imageWidth) { // ...some logic that sets the views } } 

И вот XML:

 <merge xmlns:android="http://schemas.android.com/apk/res/android"> <ImageView android:id="@+id/imgLoader" android:layout_width="30dp" android:layout_height="30dp" android:layout_centerInParent="true" android:src="@drawable/ico_loader" /> <com.android.volley.toolbox.NetworkImageView android:id="@+id/thumbnail" android:layout_width="wrap_content" android:layout_height="wrap_content" /> </merge>