RelativeLayout использует полноэкранный режим для wrap_content

Почему FOOBARZ выкладывается полностью внизу, когда нет элементов layout_height="fill_parent" другими словами, все элементы имеют wrap_content для высоты?

<?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="wrap_content">
    <TextView
        android:id="@+id/feed_u"
        android:layout_width="50dip"
        android:layout_height="50dip"
        android:layout_marginLeft="5dip"
        android:scaleType="centerCrop"
        android:drawableTop="@android:drawable/presence_online"
        android:text="U" />
    <RelativeLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_toRightOf="@id/feed_u">
        <ImageView
            android:id="@+id/feed_h"
            android:layout_alignParentRight="true"
            android:layout_alignParentTop="true"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@android:drawable/btn_minus" />
        <ImageView
            android:id="@+id/feed_ha"
            android:layout_toLeftOf="@id/feed_h"
            android:layout_alignParentRight="true"
            android:layout_alignParentTop="true"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@android:drawable/btn_plus" />
        <TextView
            android:id="@+id/feed_t"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Title">
        </TextView>
        <TextView
            android:id="@+id/feed_a"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Band"
            android:layout_below="@id/feed_t">
        </TextView>
        <TextView
            android:id="@+id/feed_s"
            android:layout_below="@id/feed_a"
            android:text="S"
            android:layout_height="wrap_content"
            android:layout_width="wrap_content">
        </TextView>
        <TextView
            android:id="@+id/feed_tm"
            android:layout_alignParentBottom="true"
            android:layout_alignParentRight="true"
            android:text="FOOBARZ"
            android:layout_height="wrap_content"
            android:layout_width="wrap_content">
        </TextView>

    </RelativeLayout>
</RelativeLayout>

8 ответов

Решение

От RelativeLayout документ:

Обзор класса

Макет, в котором позиции детей могут быть описаны по отношению друг к другу или к родителю.

Обратите внимание, что у вас не может быть круговой зависимости между размером RelativeLayout и положением его дочерних элементов. Например, у вас не может быть RelativeLayout, высота которого установлена ​​на WRAP_CONTENT, а дочерний элемент - на ALIGN_PARENT_BOTTOM

Документация класса

Что именно ваш случай. RelativeLayout не может этого сделать.

Для тех, кто ищет решение этой проблемы, как и я, вы можете использовать FrameLayout вместо RelativeLayout,

Затем вы можете установить гравитацию предполагаемого объекта в правом нижнем углу, как показано ниже

<TextView
    android:layout_gravity="bottom|right"
    android:text="FOOBARZ"
    android:layout_height="wrap_content"
    android:layout_width="wrap_content">
</TextView>

Вы установили для RelativeLayout значение "wrap_content" и TextView для android:layout_alignParentBottom="true", поэтому он автоматически пытается растянуть RelativeLayout до дна. Не используйте такие зависимости с Relative Layout, так как это может считаться "циклическими зависимостями".

Из документов для RelativeLayout:

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

Попробуйте выровнять ваш TextView с чем-то отличным от родительского RelativeLayout, но следите также за этой проблемой:
Круговые зависимости, нужна помощь с точным кодом

Кроме того, попробуйте добавить более сложные внутренние макеты.

Не используйте свойства типа alight_Parent с дочерними представлениями

Вы можете использовать структуру кадра вместо RelativeLayout с соответствующей силой тяжести

    <FrameLayout
    android:layout_height="wrap_content"
    android:layout_width="wrap_content">
     <TextView
        android:layout_gravity="bottom|right"
        android:text="Hello "
        android:layout_height="wrap_content"
        android:layout_width="wrap_content">

    </TextView>

</FrameLayout>

FrameLayoutобычно хорошо подходит для размещения разных представлений друг над другом (где самый последний дочерний элемент находится поверх предыдущего дочернего элемента). В вашем случае вы хотели бы разместить представления одно рядом с другим (выше, ниже, начало, конец), поэтому я думаю, что это лучше, потому что это именно то, что он делает.

В отличие от RelativeLayout, вы сможете установить ConstrainLayoutширина до wrap_contentи по-прежнему упорядочивать его дочерние представления по своему усмотрению, например, вместо

      android:layout_alignParentTop="true"

ты можешь использовать

      grid:layout_constraintTop_toTopOf="parent" 

и вместо

      android:layout_alignParentBottom="true"

ты можешь использовать

      grid:layout_constraintBottom_toBottomOf="parent"

Я не уверен, почему чистый и очевидный способ сделать это еще не был опубликован. Это эффективное решение работает для любого View MyView с известной высотой.

Оберните RelativeLayout с высотой wrap_content в FrameLayout:

<!-- width here should constrain RelativeLayout -->
<FrameLayout 
     android:layout_width="@dimen/my_layout_width"
     android:layout_height="wrap_content">

     <RelativeLayout  
          android:layout_width="match_parent"
          android:layout_height="wrap_content" />

     <MyView
        ...
        android:layout_gravity="bottom" />
</FrameLayout>

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

Не уверен, почему все ответы здесь предполагают , который предназначен для рендеринга одного вида или видов, наслоенных по оси Z. Проблема ОП - это последовательность представлений, сложенных вертикально, которая должна быть в .

Хорошие ответы. Теперь, если у вас нет layout_alignParentBottom="true" и до сих пор получать эту проблему остерегаться android:background="@drawable/bkgnd" где bkgnd - важная персона

Другие вопросы по тегам