2010-04-29 12 views
5

Actualmente estoy trabajando en una pequeña actualización de un proyecto y tengo un problema con Relative_Layout y fill_parent en una vista de lista. Estoy tratando de insertar un divisor entre dos secciones en cada fila, al igual que el divisor en el registro de llamadas del marcador predeterminado. Revisé el código fuente de Android para ver cómo lo hacían, pero encontré un problema al replicar su solución.Android RelativeLayout fill_parent comportamiento inesperado en un ListView con alturas de filas variables

Para empezar, aquí es mi diseño elemento de la fila:

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

El problema que estoy enfrentando es que cada fila tiene una miniatura de altura variable (ImageView01). Si configuro la propiedad layout_height de RelativeLayout en fill_parent, el divisor no se escala verticalmente para llenar la fila (solo queda un punto de 1px). Si configuro layout_height en "? Android: attr/listPreferredItemHeight", el divisor llena la fila, pero las miniaturas se contraen. He depurado el método getView() del adaptador, y parece que la altura del divisor no se establece correctamente una vez que la fila tiene su altura adecuada.

Aquí está una parte del método getView():

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

El resto del método simplemente establece el texto y las imágenes apropiado para la fila.

También, crear el objeto de inflado en el constructor del adaptador con: inflater = LayoutInflater.from(context);

Me estoy perdiendo algo esencial? ¿O fill_parent simplemente no funciona con alturas dinámicas?

Respuesta

0

Sospecho que existe una dependencia circular en su diseño. ¿Seguro que quiere que la fila layout_height sea fill_parent? Parece que desea que la fila tenga la misma altura que la subvista más grande (@id/ImageView01 en este caso), por lo que desea layout_height="wrap_content" en el RelativeLayout. De esta manera, la altura se propagará de la imagen a la fila y luego a los otros niños que tienen layout_height="fill_parent".

+0

¡Gracias por la respuesta! Sin embargo, el divisor aún no llenará la fila verticalmente. No estoy seguro de si este comportamiento es un error o si me falta algo más. ¿Alguna otra idea? –

0

Para cualquier persona que tenga curiosidad. Parece que esto puede ser (o ha sido) un error en el SDK. Para solucionar el problema, tuve que ir con alturas de fila fijas. Este es el código de diseño final:

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

Si alguien más se encuentra con este problema, la única forma que he encontrado (aparte de altura fija) es cambiar a un LinearLayout. Supongo que esto se debe a una diferencia fundamental en cómo se dibujan LinearLayouts vs. RelativeLayouts. Romain Guy habla de ello en el artículo this. LinearLayouts llama a Measure (Measure) una vez para el ancho y una para la altura, donde como RelativeLayouts no, por lo que no tienen forma de retroceder y completar un divisor vertical a la altura adecuada una vez que todo lo demás se ha establecido. La solución de la siguiente manera:

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

Esto debe obtener el resultado deseado, aunque no es tan eficiente como un único RelativeLayout.

Cuestiones relacionadas