Подтвердить что ты не робот

Как заставить RelativeLayout работать с объединением и включать?

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

4b9b3361

Ответ 1

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

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

Ответ 2

См. более проголосовавший ответ ниже. Моя устало устарела


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

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

Каждый из них должен иметь уникальный родительский контейнер, и вы вызов 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>

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

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

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

Ответ 3

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

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

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

Ответ 4

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

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

Ответ 5

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

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

Кроме того, если кто-то может подумать о способе мне просто нужно иметь один слияние xml-макета файл вместо 5, который будет очень ценится.

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

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

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

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

Ответ 6

В моем случае макет, который я пытался включить, начинается с тега <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">