2010-09-16 13 views
13

¿Se puede usar addHeaderView() de Android para agregar varios encabezados en un solo ListView? ¿Alguien puede dar un ejemplo de cómo hacer esto?Cómo agregar varios encabezados en un solo ListView con addHeaderView()?

Pude lograr lo que quería manipulando la clase IconicAdapter ... ¿hay alguna razón por la que no debería hacerlo de esta manera? Siento que esto podría modificarse para implementaciones más avanzadas. En mi caso, sé que tendré dos secciones, con un encabezado + 2 filas en cada sección.

class IconicAdapter extends ArrayAdapter<String> { 
    IconicAdapter() { 
     super(ContactTabProfileResource.this, R.layout.row_iconic, mArrayList); 
    } 


    public View getView(int position, View convertView, ViewGroup parent) { 

     LayoutInflater inflater = getLayoutInflater(); 
     View row = null; 

     if(position == 1 || position == 5) { // phone 
      row = inflater.inflate(R.layout.row_iconic, parent, false); 
      TextView label =(TextView)row.findViewById(R.id.label); 
      label.setText(mArrayList.get(position)); 
      ImageView icon = (ImageView)row.findViewById(R.id.rowicon); 
      icon.setImageResource(R.drawable.icon_phone); 
     } else if (position == 2 || position == 6) { // email 
      row = inflater.inflate(R.layout.row_iconic, parent, false); 
      TextView label =(TextView)row.findViewById(R.id.label); 
      label.setText(mArrayList.get(position)); 
      ImageView icon = (ImageView)row.findViewById(R.id.rowicon); 
      icon.setImageResource(R.drawable.icon_email); 
     } else if (position == 0 || position == 4) { // section header 
      row = inflater.inflate(R.layout.row_header, parent, false); 
      TextView label =(TextView)row.findViewById(R.id.label); 
      label.setText(mArrayList.get(position)); 
      label.setBackgroundColor(Color.GRAY); 
     } else if (position == 3) { // section divider 
      row = inflater.inflate(R.layout.row_header, parent, false); 
      TextView label =(TextView)row.findViewById(R.id.label); 
      label.setText(" "); 
     } 

     return(row); 

    } 
} 

Luego creé dos diseños XML diferentes. row_header.xml es para las filas del encabezado y row_iconic.xml es para las filas sin encabezado, que contienen un ícono.

row_header.xml

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

    <TextView 
    android:id="@+id/label" 
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:textSize="20sp" 
    android:paddingTop="10dp" 
    android:paddingBottom="10dp" 
    android:paddingRight="10dp" 
    android:paddingLeft="10px" 
    android:gravity="left" 
    android:textStyle="bold" 
    />  
</LinearLayout> 

row_iconic.xml

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

    <TextView 
    android:id="@+id/label" 
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:textSize="16sp" 
    android:paddingTop="10dp" 
    android:paddingBottom="10dp" 
    android:paddingRight="10dp" 
    android:paddingLeft="44px" 
    /> 
    <ImageView 
    android:id="@+id/rowicon" 
    android:layout_width="40dp" 
    android:paddingRight="10dp" 
    android:paddingTop="10dp" 
    android:layout_height="30dp"   
    android:src="@drawable/icon" 
    />  
</LinearLayout> 

Respuesta

13

Lo que quiere que los desarrolladores de Android llamen un separador de listas o un subtítulo ("encabezados" y "pies de página" solo se muestran en la parte superior o inferior de la lista). La esencia de cómo puede hacer esto es usar un ListAdapter que envuelve a otros ListAdapters y es lo suficientemente inteligente como para devolver un tipo de vista de encabezado para ciertas filas y hacer un seguimiento de los desplazamientos, o envuelve esas vistas de separador en sus propios mini adaptadores.

Tome un vistazo a la marca Murphy SectionedListAdapter, GPL, que toma el primer enfoque (basado en el código de Jeff Sharkey), o su MergeAdapter, y ver this SO question.

Está muy lejos del manejo elegante de los subtítulos de la lista inteligente en el iPhone, pero es bastante sencillo utilizar MergeAdapter y es muy flexible una vez que entienda exactamente lo que sucede dentro de los adaptadores.

1

Puede añadir tantas cabeceras como te gusta llamando addHeaderView() varias veces. Tienes que hacerlo antes de configurar el adaptador a la vista de lista.

+0

Puedo agregar varias vistas de encabezado ... pero todas aparecen en la parte superior de ListView. Me gustaría usar encabezados para crear secciones dentro de ListView. No estoy seguro de cómo hacer que los encabezados aparezcan en cualquier lugar que no sea la parte superior de ListView – Chris

7

Si desea devolver diseños diferentes (por ejemplo, los artículos & encabezados) tiene que usar getItemViewType(int position). Por lo tanto, su código de adaptador debería verse así:

private static final int TYPE_HEADER = 0; 
private static final int TYPE_ICONIC = 1; 

@Override 
public int getViewTypeCount() { 
    return 2; // we have two types, so just return 2 
} 

@Override 
public int getItemViewType(int position) { 
    // TODO: return TYPE_HEADER here if this position is a header, otherwise return TYPE_ICONIC 
} 

@Override 
public View getView(int position, View convertView, ViewGroup parent) { 
    // TODO: return the appropriate layout 
    // hint: you might call getItemViewType(position) yourself here to know of which type the layout is 
} 

Así es básicamente como funciona. Para asegurarse de que los encabezados no son seleccionables, puede desear tirar ArrayAdapter y usar ListAdapter en su lugar, anulando isEnabled(int position) para devolver false para sus vistas de encabezado. ;-)

0

También puede usar this class como ejemplo. Admite "secciones" y "acciones", donde "secciones" son solo grupos de "acciones" (elementos), tienen elementos no seleccionables y no seleccionables: encabezado. "Acciones" puede especificar el controlador onClick al que se llamará cuando se presione esta "acción", si existe. También contiene ImageLoader para buscar imágenes de las "acciones" de la web.

Cuestiones relacionadas