В течение нескольких дней я пытался сделать свои макеты более эффективными, преобразовав использование нескольких уровней вложенности LinearLayouts
в один, RelativeLayout
и столкнулся с несколькими проблемами, для которых я не смог найти обходной путь ...
Я искал группу для начинающих Android и этот сайт и не смог найти ничего, что помогло бы мне решить проблему.
Я прочитал в одном из блогов, что вы можете комбинировать макеты с помощью тегов слияния и включения. Итак, у меня есть основной файл макета с RelativeLayout
корневым элементом. Внутри у меня есть 5 тегов include, которые ссылаются на 5 разных файлов макета xml, каждый из которых имеет элемент слияния для корня (все мои файлы слияния одинаковы, за исключением идентификаторов в них).
Я столкнулся с двумя проблемами, которые я объясню после публикации упрощенной версии моего кода макета:
Пример основного файла макета:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="@drawable/translucent_gray" >
<include
android:id="@+id/running_gallery_layout_id"
layout="@layout/running_gallery_layout" />
<include
android:id="@+id/recent_gallery_layout_id"
layout="@layout/recent_gallery_layout"
android:layout_below="@id/running_gallery_layout_id" />
<include
android:id="@+id/service_gallery_layout_id"
layout="@layout/service_gallery_layout"
android:layout_below="@id/recent_gallery_layout_id" />
<include
android:id="@+id/process_gallery_layout_id"
layout="@layout/process_gallery_layout"
android:layout_below="@id/service_gallery_layout_id" />
</RelativeLayout>
Пример включенного файла слияния:
<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android">
<TextView
style="@style/TitleText"
android:id="@+id/service_gallery_title_text_id"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="left"
android:text="@string/service_title" />
<Gallery
android:id="@+id/service_gallery_id"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_below="@id/service_gallery_title_text_id" />
<TextView
style="@style/SubTitleText"
android:id="@+id/service_gallery_current_text_id"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="@id/service_gallery_title_text_id"
android:layout_above="@id/service_gallery_id" />
</merge>
У меня две проблемы:
1) android:layout_*
Кажется, что атрибуты игнорируются при использовании в теге include, и все объединенные макеты отображаются друг над другом. Согласно этому сообщению ( http://developer.android.com/resources/articles/layout-tricks-reuse.html ) «любой android:layout_*
атрибут может использоваться с <include />
тегом»
2) Поскольку я не мог заставить это работать, я решил попробовать добавить android:layout_below
атрибут к первому TextView
элементу в каждом файле макета слияния, что означает, что каждый файл слияния будет ссылаться на идентификатор из другого файла макета слияния ... По большей части это действительно сработал, и мой макет выглядит нормально. Однако я получаю сообщение об ошибке в одном из android:layout_below
атрибутов, в котором говорится, что он не может найти указанный мной идентификатор ... Я дважды и трижды проверил идентификаторы, чтобы убедиться, что они верны. Самое странное то, что я использовал эту AutoFill
функцию, чтобы поместить идентификатор в атрибут в первую очередь.
Если у кого-то есть предложения или обходные пути, я буду более чем счастлив попробовать их. Кроме того, если кто-нибудь может придумать для меня способ иметь только один файл макета слияния xml вместо 5, это будет очень признательно. Я не мог найти способ сделать это, потому что мне нужен доступ к каждому элементу в файлах макета слияния во время выполнения ...
layout_width
иlayout_height
другое<include>
. Я пробовал также установитьlayout_width
иlayout_height
на моем,<merge>
но безуспешно. Что мне не хватает?См. Ответ, получивший наибольшее количество голосов ниже. Моя ужасно устарела
Я могу решить одну проблему, поднятую Джастином : неспособность RelativeLayout управлять позиционированием включения (по крайней мере, в этом простом случае на эмуляторе 1.6)
CommonsWare предлагает обертывание включает в уникальном родительском контейнере, но делает это для того , чтобы помочь решению и обзорным одинаково именованных видов внутри Джастина включает
Фактически, вы также должны сделать это , чтобы RelativeLayout работал так, как ожидалось:
Это работает ( нижний колонтитул расположен хорошо):
Этого не происходит ( нижний колонтитул плавает вверху экрана):
Включаемый нижний колонтитул не будет выровнен по низу родительского объекта без окружающего его LinearLayout .. Я бы не назвал это ожидаемым поведением.
Кроме того, WebView, кажется, красиво прикрепляется к заголовку по идентификатору, но я считаю, что это иллюзия, потому что он просто течет под заголовком по вертикали. Я также попытался установить кнопку прямо над включением нижнего колонтитула, но она тоже стала плавной и неправильной
В RelativeLayout было больше проблем в 1.5, но он мне все равно нравится :)
источник
Чувак, это старый, но, похоже, он находится в верхней части поисковых запросов, поэтому я собираюсь прокомментировать.
Я думаю, что хитрость здесь в том, что
<merge>
тег в сочетании с<include>
тегом по существу удаляет любую «родительскую» группу представлений на этом уровне. Итак, кого именно вы просите "layout_below" кого-то еще? Ни один. Никто. На этом уровне нет обзора.<merge>
Тег принимает мнения ребенка и хлопает их прямо в родителю<include>
тега. Поэтому вы должны попросить детей в макете, который вы включаете, соответствующим образом закрепить себя.источник
Чтобы позиционирование работало в RelativeLayout, вам необходимо установить параметры layout_ * во включаемом файле, а не в основном файле макета. Туда
main_layout.xml
content_layout.xml
Это явно не то, чего хотят мы, разработчики, но это единственное решение, которое я нашел, чтобы избежать дублирования xml.
источник
Я предполагаю, что из правил компоновки нельзя ссылаться на
android:id
атрибуты, определенные в<include>
элементах, только на те, которые находятся в «реальных» виджетах и контейнерах.Просто: поместите их все в один файл.
Независимо от того, есть ли у вас один
<include>
элемент или 1000, все содержимое должно быть доступно во время выполнения. Единственное исключение - если у вас есть дублированныеandroid:id
атрибуты - вам нужно будет правильно определить область вашихfindViewById()
вызовов, чтобы получить нужный, как и при получении виджетов из строки ListView.Если вы можете создать пример проекта , который использует 2+ слияния файлов , где вы можете продемонстрировать , что содержимое не доступны во время выполнения, дайте мне знать.
источник
пытаться :
источник
В моем случае макет, который я пытался включить, начинается с
<merge
тега. Когда я изменил его на макет, говорят, что<RelativeLayout
он работал. Ниже представлена иллюстрация.РАБОТАЕТ
НЕ РАБОТАЕТ
источник
У меня была такая же проблема и даже определение,
layout_width
иlayout_height
это не сработало. Проблема заключалась в том, что в макете, который я включал, были теги, и после их удаления все работало как шарм. Я полагаю, что слияние не является тегом макета и из-за этого не может получать параметры позиционирования и размера. Поскольку все, что вы определяете, переносится во внутренний родительский макет, настройки просто выбрасываются.TL: DR: Просто удалите теги, переместите определения xmlns в реальный просмотрщик макета, и все будет хорошо.
Перед:
Работает:
источник