2010-03-16 16 views
6

Estoy usando una vista de lista en Android 1.5 para mostrar una lista de imágenes y texto al lado de la imagen. Intento centrar verticalmente el texto, pero el texto está en la parte superior de la fila en lugar de estar centrado. A continuación se muestra mi diseño:¿Cómo alinear verticalmente un elemento dentro de una lista usando el diseño relativo?

<?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> 

Parece extraño que necesito fijar alignParentTop = "true" cuando estoy tratando de centrar verticalmente el texto, pero si lo hago no el texto ni siquiera se presentó. ¿Qué estoy haciendo mal?

Respuesta

16

EDITAR siguiendo los comentarios:

Resulta hacer este trabajo con RelativeLayout no es fácil. En la parte inferior de la respuesta, he incluido un RelativeLayout que proporciona el efecto deseado, pero solo hasta que esté incluido en un ListView. Después de eso, ocurrieron los mismos problemas que se describen en la pregunta. Esto se solucionó mediante el uso de 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> 

Si usted quiere tener dos cuadros de texto, puede anidar una segunda orientation="vertical" y LinearLayout después de la ImageView y luego poner los cuadros de texto en ese país.

Esto funciona, pero tengo que admitir que no sé por qué RelativeLayouts no lo hizo. Por ejemplo, este blog post by Romain Guy dice específicamente que el RelativeLayout debería. Cuando lo probé, nunca funcionó; es cierto que no lo hice exactamente como lo hizo, pero mis únicos cambios fueron con algunos atributos de los TextViews, que no deberían haber hecho una gran diferencia.


Aquí está la respuesta original:

Creo que estás confundiendo Android con todas esas instrucciones tanto contradictorios en RelativeLayout. Volví a formatear lo tuyo a esto:

<?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> 

Y eso funciona bien. Eliminé muchos de sus android:layout_alignParentxxx redundantes porque no eran necesarios. Esta vista ahora aparece con la imagen en la esquina superior izquierda y el texto centrado verticalmente al lado. Si también quieres que la imagen esté centrada verticalmente, no puedes hacer que RelativeLayout esté en android: layout_height = "wrap_content" porque está tratando de no ser más alto que el alto de la imagen. Debería especificar una altura, p. 80dp, y luego configure el ImageView a una altura fija como 60dp con android: scaleType = "fitXY" para que se ajuste a escala de forma adecuada.

+0

Gracias por intentarlo. Quiero que el diseño no sea más alto que la imagen, por lo que la imagen está bien.Probé tu xml, y veo lo mismo que estaba viendo con el mío. El texto no aparece a menos que agregue android: layout_alignParentTop = "true" a TextView, y luego, por supuesto, está justificado en la parte superior en lugar de centrado. ¿Pusiste el tuyo dentro de un ListView? –

+0

Hmm. Funcionó bien cuando era una Vista en sí misma, pero cuando lo agregué a un ListView, entonces sí, dejó de funcionar. Acabo de probar algunas cosas y nada ha funcionado del modo en que debería haberlo hecho con RelativeLayout. Sin embargo, puedes lograr el mismo efecto usando LinearLayout. Establezca la orientación en horizontal y luego haga que la altura de TextView sea fill_parent, con center_vertical gravedad. Si desea tener varios TextViews junto al icono, puede colocarlos dentro de un segundo LinearLayout vertical. Esto no es elegante, pero no puedo entender por qué RelativeLayouts no estaba funcionando ... –

+0

¿Podría editar su respuesta para mencionar LinearLayout? Eso parece funcionar. –

0

Baseline directive lo haría, pero ImageView simplemente no es compatible con la alineación de línea base a partir de hoy. Puede solucionar esto creando una subclase de ImageView, anular el método getBaseline() y devolver el alto de la imagen.

+0

Gracias, intentaré esto esta noche para ver si funciona. Parece una pena tener que subclase ImageView, pero lo probaré. –

1

quedado atrapado en un problema similar durante un tiempo, pero encontramos esto desde CommonsWare:

"Cuando se infla el diseño, utilice inflate(R.layout.whatever, parent, false), donde el padre es el ListView."

Funciona pero solo cuando configura la altura de la fila a un valor específico (es decir, no puede usar wrap_content).

Cuestiones relacionadas