Как получить RelativeLayout работает с merge и include?


я пытался в течение нескольких дней, чтобы сделать мои макеты более эффективными путем преобразования из использования нескольких уровней вложенных LinearLayouts один RelativeLayout и столкнулись с несколькими проблемами,которые я не смог найти обходной путь...

я искал группу начинающих Android и этот сайт и не смог найти ничего, что помогло бы мне решить эту проблему.

я читал в одном из блогов, что вы можете комбинировать макеты с слиянием и включают в себя теги. Так что у меня есть основной файл макета с RelativeLayout корневой элемент. Внутри этого у меня есть 5 тегов, которые ссылаются на 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) The 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, который был бы очень признателен. Я не мог найти способ сделать это, потому что мне нужно иметь доступ к каждому элементу в файлах макета слияния во время выполнения...

7 113

7 ответов:

существует проблема с тегом include. Проверьте:https://issuetracker.google.com/issues/36908001

чтобы исправить это, убедитесь, что вы перезаписали как layout_width и layout_height при включении, иначе все будет проигнорировано.

смотрите более высоко проголосовали ответ ниже. Моя, к сожалению, устаревают


Я могу решить одну проблему Джастин raised: неспособность RelativeLayout управлять позиционированием include (по крайней мере, в этом простом случае, на эмуляторе 1.6)

CommonsWare предлагает обернуть includes в уникальный родительский контейнер, но делает это для того, чтобы помочь адресации и области видимости с одинаковыми именами внутри Джастина включает в себя

каждый должен был бы иметь уникальный родительский контейнер, и вы бы вызов findViewById () на этом контейнере (ViewGroup), а не на Деятельность.

на самом деле, ты тоже надо это сделать чтобы получить RelativeLayout вести себя так, как ожидалось:

это работает (нижний колонтитул хорошо):

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent" android:layout_height="fill_parent">
    <include android:id="@+id/header" layout="@layout/header"
        android:layout_alignParentTop="true" />
    <WebView android:id="@+id/webView" android:layout_below="@id/header"
        android:background="#77CC0000" android:layout_height="wrap_content"
        android:layout_width="fill_parent" android:focusable="false" />
    <LinearLayout android:layout_alignParentBottom="true"
        android:layout_height="wrap_content" android:layout_width="fill_parent">
        <include android:id="@+id/footer" layout="@layout/footer" />
    </LinearLayout>
</RelativeLayout>

это не имеет (нижний колонтитул плавает в верхней части экрана):

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent" android:layout_height="fill_parent">
    <include android:id="@+id/header" layout="@layout/header"
        android:layout_alignParentTop="true" />
    <WebView android:id="@+id/webView" android:layout_below="@id/header"
        android:background="#77CC0000" android:layout_height="wrap_content"
        android:layout_width="fill_parent" android:focusable="false" />
    <include android:id="@+id/footer" layout="@layout/footer"
        android:layout_alignParentBottom="true" />
</RelativeLayout>

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

кроме того, WebView, похоже, хорошо прикрепляется к заголовок по ID, но я считаю, что это иллюзия, из-за него просто течет ниже заголовка вертикально. Я также попытался установить кнопку прямо над Нижним колонтитулом, но она стала плавающей и неправильная, слишком

RelativeLayout было больше проблем в 1.5, но мне все равно нравится:)

человек, это старый, но он, кажется, пришел в верхней части поисков, так что я собираюсь прокомментировать.

Я думаю, что трюк здесь в том, что <merge> тег в сочетании с <include> тег по существу удаляет любую "родительскую" группу представлений на этом уровне. Итак, кого именно вы просите "layout_below" кого-то другого? Никто. Нет на этом уровне.

The <merge> тег принимает дочерние представления и помещает их прямо в родительский элемент <include> тег. Вы должны поэтому попросите детей в макете, который вы включаете, закрепить себя соответствующим образом.

для позиционирования для работы на RelativeLayout вам нужно установить layout_ * параметры в файле include, а не в главном файле макета. Вот так

main_layout.XML

<RelativeLayout
  android:id="@+id/header"
  android:layout_width="fill_parent"
  android:layout_height="wrap_content">
   ....
</RelativeLayout>

<RelativeLayout 
  android:id="@+id/footer"
  android:layout_width="fill_parent"
  android:layout_height="wrap_content"
  android:layout_alignParentBottom="true">
    .....
</RelativeLayout>

<include layout="@layout/content_layout" />

content_layout.xml

<merge xmlns:android="http://schemas.android.com/apk/res/android">
<RelativeLayout
    android:id="@+id/content"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:layout_above="@id/footer"
    android:layout_below="@id/header" >

    ....
</RelativeLayout>
</merge>

это явно не то, что хотят американские разработчики, но это единственное решение, которое я нашел, чтобы избежать дублирования xml

android: layout_ * атрибуты кажутся игнорируется при использовании в тег и все объединенные макеты являются отображаются друг на друге.

Я предполагаю, что вы не можете ссылаться, из правил макета,android:id атрибуты, которые определены на <include> элементы, только те, которые находятся на "реальных" виджетов и контейнеров.

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

просто: поместите их все в один файл.

Я не мог найти способ сделать это потому что мне нужно иметь доступ к каждой элемент в файлах макета слияния по адресу время работы

есть ли у вас один <include> элемент или 1000, все содержание должно быть доступно во время выполнения. Одно исключение, если вы продублировали android:id атрибуты -- вам нужно будет правильно охватить ваш findViewById() запросы на получение правильно, как и при получении виджетов из строки ListView.

если вы можете создать пример проекта, который использует 2 + файлы слияния, где вы можете продемонстрировать, что содержимое не доступно во время выполнения, дайте мне знать.

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

работающего

<RelativeLayout xmlns:tools="http://schemas.android.com/tools"
    xmlns:android="http://schemas.android.com/apk/res/android"
    tools:showIn="@layout/activity_home">

НЕ РАБОТАЕТ

<merge xmlns:tools="http://schemas.android.com/tools"
    xmlns:android="http://schemas.android.com/apk/res/android"
    tools:showIn="@layout/activity_home">

у меня была такая же проблема и даже определение layout_width и layout_height это не сработало. Проблема была в том, что макет, который я включал, имел теги, и после их удаления все работало как шарм. Я полагаю, что merge не является тегом макета, и из-за этого он не может получать параметры позиционирования и размера. Поскольку все, что вы определяете, передается во внутренний Родительский макет,настройки просто были выброшены.

TL: DR: просто удалите теги, переместите xmlns определения к реальному viewholder макета, и вы должны быть хороши.

перед:

<merge
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <...ui.component.BorderCardView
        android:layout_width="112dp"
        android:layout_height="32dp"
        app:cardCornerRadius="4dp"
        app:cardUseCompatPadding="true">

        <ImageView
            android:layout_width="16dp"
            android:layout_height="16dp"
            android:src="@drawable/ic_logout"
            android:tint="@color/divider" />

    </...ui.component.BorderCardView>
</merge>

работает:

<...ui.component.BorderCardView
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="112dp"
    android:layout_height="32dp"
    app:cardCornerRadius="4dp"
    app:cardUseCompatPadding="true">

    <ImageView
        android:layout_width="16dp"
        android:layout_height="16dp"
        android:src="@drawable/ic_logout"
        android:tint="@color/divider" />

</...ui.component.BorderCardView>