Неожиданное поведение Android RelativeLayout fill_parent в ListView с переменной высотой строки - PullRequest
5 голосов
/ 29 апреля 2010

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

Для начала вот мое расположение элементов строки:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout android:id="@+id/RelativeLayout01"
 android:layout_width="fill_parent" 
 xmlns:android="http://schemas.android.com/apk/res/android"
 android:padding="10dip" 
 android:layout_height="fill_parent" 
 android:maxHeight="64dip" 
 android:minHeight="?android:attr/listPreferredItemHeight">
 <ImageView android:id="@+id/infoimage" 
  android:layout_width="wrap_content"
  android:layout_height="wrap_content" 
  android:clickable="true"
  android:src="@drawable/info_icon_big" 
  android:layout_alignParentRight="true" 
  android:layout_centerVertical="true"/>
 <View android:id="@+id/divider" 
  android:background="@drawable/divider_vertical_dark" 
  android:layout_marginLeft="11dip" 
  android:layout_toLeftOf="@+id/infoimage" 
  android:layout_width="1px" 
  android:layout_height="fill_parent"
  android:layout_marginTop="5dip" 
  android:layout_marginBottom="5dip" 
  android:layout_marginRight="4dip"/>
 <TextView android:id="@+id/TextView01" 
  android:textAppearance="?android:attr/textAppearanceLarge"
  android:layout_width="wrap_content" 
  android:layout_height="wrap_content"
  android:layout_centerVertical="true" 
  android:layout_toRightOf="@+id/ImageView01" 
  android:layout_toLeftOf="@+id/divider"
  android:gravity="left|center_vertical" 
  android:layout_marginLeft="4dip" 
  android:layout_marginRight="4dip"/>
 <ImageView android:id="@+id/ImageView01" 
  android:layout_width="wrap_content" 
  android:layout_height="wrap_content" 
  android:layout_alignParentLeft="true" 
  android:background="@drawable/bborder" 
  android:layout_centerVertical="true"/>
</RelativeLayout>

Проблема, с которой я сталкиваюсь, заключается в том, что в каждой строке есть эскиз различной высоты (ImageView01). Если для свойства layout_height объекта RelativeLayout установить значение fill_parent, разделитель не масштабируется по вертикали для заполнения строки (он просто остается точкой в ​​1 пиксель). Если я установлю layout_height на «? Android: attr / listPreferredItemHeight», разделитель заполняет строку, но уменьшенные изображения уменьшаются. Я выполнил некоторую отладку в методе getView () адаптера, и кажется, что высота делителя не устанавливается должным образом, когда строка имеет правильную высоту.

Вот часть метода getView ():

public View getView(int position, View view, ViewGroup parent) {
            if (view == null) {
                view = inflater.inflate(R.layout.tag_list_item, parent, false);
            }

Остальная часть метода просто устанавливает соответствующий текст и изображения для строки.

Кроме того, я создаю объект inflater в конструкторе адаптера с помощью: inflater = LayoutInflater.from(context);

Я что-то упустил? Или fill_parent просто не работает с динамическими высотами?

Ответы [ 3 ]

6 голосов
/ 01 августа 2011

Если кто-то еще столкнется с этой проблемой, единственный способ, который я нашел (кроме фиксированной высоты), это переключиться на LinearLayout. Я предполагаю, что это происходит из-за принципиальной разницы в том, как нарисованы LinearLayouts и RelativeLayouts. Ромэн Гай рассказывает об этом в этой статье. LinearLayouts вызывает onMeasure () один раз для ширины и один раз для высоты, где, как и RelativeLayouts, нет, поэтому у них нет возможности вернуться назад и заполнить вертикальный делитель на высоту пропеллера после того, как все остальное было размечено. Решение следующее:

<LinearLayout xmlns:...
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal"
    >
    <RelativeLayout android:id="@+id/leftContent"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        >
    </RelativeLayout>
    <View android:id="@+id/divider"
        android:layout_width="1px"
        android:layout_height="fill_parent"
        android:background="@drawable/divider" />
    <RelativeLayout android:id="@+id/rightContent"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        >
    </RelativeLayout>
</LinearLayout>

Это должно дать вам желаемый результат, хотя он не так эффективен, как только RelativeLayout.

0 голосов
/ 09 декабря 2010

Для всех, кому интересно. Похоже, что это может быть (или было) ошибка в SDK. Чтобы решить проблему, мне пришлось идти с фиксированной высотой ряда. Это окончательный код макета:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout android:id="@+id/RelativeLayout01"
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_height="100dip" android:layout_width="fill_parent">
    <RelativeLayout android:id="@+id/Thumbnail"
        android:layout_alignParentLeft="true" android:paddingLeft="10dip"
        android:paddingTop="10dip" android:paddingRight="15dip"
        android:paddingBottom="10dip" android:layout_height="fill_parent"
        android:layout_width="wrap_content">
        <ImageView android:id="@+id/image"
            android:layout_width="80dip" android:background="@drawable/bborder"
            android:layout_centerVertical="true" android:adjustViewBounds="true"
            android:layout_height="80dp" android:cropToPadding="true" />
    </RelativeLayout>
    <View android:id="@+id/divider" android:background="@drawable/divider_light"
        android:layout_toRightOf="@+id/Thumbnail" android:layout_marginTop="10dip"
        android:layout_marginBottom="10dip" android:layout_width="1px"
        android:layout_height="fill_parent" android:layout_alignParentTop="true"
        android:layout_alignParentBottom="true" />
    <LinearLayout 
        android:layout_width="wrap_content" android:layout_height="wrap_content"
        android:paddingTop="10dp" android:paddingBottom="10dp" 
        android:layout_centerVertical="true" android:orientation="vertical"
        android:layout_marginLeft="20dip" android:layout_marginRight="10dip"
        android:layout_toRightOf="@+id/divider">
        <TextView android:id="@+id/title" android:textAppearance="?android:attr/textAppearanceMedium"
            android:layout_width="wrap_content" android:layout_height="wrap_content"
            android:gravity="left|center_vertical" android:maxLines="1" android:singleLine="true"
            android:ellipsize="end" />
        <TextView android:id="@+id/science_name" android:textAppearance="?android:attr/textAppearanceMedium"
            android:layout_width="wrap_content" android:layout_height="wrap_content"
            android:gravity="left|center_vertical" android:maxLines="1" android:singleLine="true"
            android:ellipsize="end" android:textStyle="italic" />
    </LinearLayout>
</RelativeLayout>
0 голосов
/ 02 мая 2010

Я подозреваю круговую зависимость в вашем макете. Вы уверены, что хотите, чтобы строка layout_height была fill_parent? Похоже, вы хотите, чтобы строка была такой же высоты, как и наибольшее подпредставление (@id/ImageView01 в данном случае), поэтому вам нужно layout_height="wrap_content" в RelativeLayout. Таким образом, высота будет распространяться от изображения к строке, а затем вниз к другим дочерним элементам, которые имеют layout_height="fill_parent".

...