Как вертикально выровнять элемент в списке, используя относительное расположение? - PullRequest
6 голосов
/ 16 марта 2010

Я использую представление списка в Android 1.5, чтобы показать список изображений и текст рядом с изображением. Я пытаюсь отцентрировать текст по вертикали, но текст находится вверху строки, а не по центру. Ниже мой макет:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/row"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:padding="10dip">

    <ImageView android:id="@+id/item_image" android:layout_width="wrap_content" 
        android:layout_height="wrap_content"  android:paddingRight="10dip" 
        android:src="@drawable/default_image" android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true"
        android:layout_alignParentBottom="true"
        android:layout_centerVertical="true"
        android:gravity="center_vertical"/>

    <TextView android:id="@+id/item_title" 
        android:layout_width="wrap_content" android:layout_height="wrap_content" 
        android:layout_toRightOf="@id/item_image" 
        android:layout_alignParentTop="true"
        android:layout_alignParentBottom="true"
        android:layout_centerVertical="true"
        android:gravity="center_vertical"
        />

</RelativeLayout>

Кажется странным, что мне нужно установить alignParentTop = "true", когда я пытаюсь центрировать текст по вертикали, но если это не так, текст даже не отображается. Что я делаю не так?

Ответы [ 3 ]

16 голосов
/ 16 марта 2010

РЕДАКТИРОВАТЬ после комментариев:

Оказывается, сделать эту работу с RelativeLayout непросто. В нижней части ответа я включил RelativeLayout, который дает желаемый эффект, но только до тех пор, пока он не будет включен в ListView. После этого возникли те же проблемы, что описаны в вопросе. Вместо этого это было исправлено с помощью LinearLayout (s).

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:paddingLeft="10dp"
    android:orientation="horizontal">

    <ImageView android:id="@+id/pickImageImage" 
        android:layout_width="100dp"
        android:layout_height="80dp"
        android:background="@drawable/icon"
        android:scaleType="fitXY"
        android:layout_marginRight="10dp"/>

    <TextView android:id="@+id/pickImageText" 
        android:layout_height="fill_parent"
        android:layout_width="fill_parent"
        android:gravity="left|center_vertical"
        android:text="I'm the text"/>

</LinearLayout>

Если вы хотите иметь два текстовых поля, вы можете вложить секунду orientation="vertical" и LinearLayout после ImageView, а затем поместить туда текстовые поля.

Это работает, но я должен признать, что не знаю, почему RelativeLayouts этого не сделал. Например, в этом сообщении в блоге Ромена Гая конкретно говорится, что RelativeLayout должен. Когда я попробовал это, я так и не смог заставить его работать; по общему признанию я не сделал это точно , поскольку он сделал, но мои единственные изменения были с некоторыми атрибутами TextViews, которые не должны были иметь такого большого значения.


Вот оригинальный ответ:

Я думаю, что вы путаете Android со всеми этими довольно противоречивыми инструкциями в RelativeLayout. Я переформатировал вашу вещь в это:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/row"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:padding="10dip">

    <ImageView android:id="@+id/item_image"
        android:layout_width="wrap_content" 
        android:layout_height="wrap_content"
        android:paddingRight="10dip" 
        android:src="@drawable/icon"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true"/>

    <TextView android:id="@+id/item_title" 
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" 
        android:layout_toRightOf="@id/item_image" 
        android:layout_centerVertical="true"
        android:text="Blah!"/>

</RelativeLayout>

И это прекрасно работает. Я удалил многие из твоих лишних android:layout_alignParentxxx, потому что они не были нужны. Теперь это представление отображается с изображением в верхнем левом углу и рядом с текстом по центру. Если вы хотите, чтобы изображение было также центрировано по вертикали, то вы не можете иметь RelativeLayout на android: layout_height = "wrap_content", потому что он пытается сделать себя не выше высоты изображения. Вы должны указать высоту, например, 80dp, а затем установите ImageView на фиксированную высоту, например, 60dp с android: scaleType = "fitXY", чтобы уменьшить его до нужного размера.

1 голос
/ 01 сентября 2010

Застрял на подобной проблеме некоторое время, но нашел это из CommonsWare:

"Когда вы раздуваете макет, используйте inflate(R.layout.whatever, parent, false), где parent - это ListView."

Работает, но только когда вы устанавливаете высоту строки на определенное значение (т.е. вы не можете использовать wrap_content).

0 голосов
/ 16 марта 2010

Базовая директива сделает это, но ImageView просто не поддерживает выравнивание базовой линии на сегодняшний день. Вы можете обойти это, создав подкласс ImageView, переопределив метод getBaseline () и вернув высоту изображения.

...