Tengo ListView que tiene algún tipo de eventos. Los eventos están ordenados por día, y me gustaría tener un encabezado con fecha para cada día, y luego los eventos se escuchan a continuación.
Así es como llego esa lista:
ArrayList<TwoText> crs = new ArrayList<TwoText>();
crs.add(new TwoText("This will be header", event.getDate()));
for (Event event : events) {
crs.add(new TwoText(event.getStartString() + "-" + event.getEndString(), event.getSubject()));
}
arrayAdapter = new TwoTextArrayAdapter(this, R.layout.my_list_item, crs);
lv1.setAdapter(arrayAdapter);
y así es como se ve mi clase TwoText:
public class TwoText {
public String classID;
public String state;
public TwoText(String classID, String state) {
this.classID = classID;
this.state = state;
}
}
y así es como se ve mi clase TwoTextArrayAdapter:
import java.util.ArrayList;
import android.app.Activity;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.TextView;
public class TwoTextArrayAdapter extends ArrayAdapter<TwoText> {
private ArrayList<TwoText> classes;
private Activity con;
TextView seperator;
public TwoTextArrayAdapter(Activity context, int textViewResourceId, ArrayList<TwoText> classes) {
super(context, textViewResourceId, classes);
this.con = context;
this.classes = classes;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
if (v == null) {
LayoutInflater vi = (LayoutInflater) con.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = vi.inflate(R.layout.my_list_item, null);
}
TwoText user = classes.get(position);
if (user != null) {
TextView content1 = (TextView) v.findViewById(R.id.list_content1);
TextView content2 = (TextView) v.findViewById(R.id.list_content2);
if (content1 != null) {
content1.setText(user.classID);
}
if(content2 != null) {
content2.setText(user.state);
}
}
return v;
}
}
y este es my_list_item.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
style="?android:attr/listSeparatorTextViewStyle"
android:id="@+id/separator"
android:text="Header"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#757678"
android:textColor="#f5c227" />
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal" >
<TextView
android:id="@+id/list_content1"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_margin="5dip"
android:clickable="false"
android:gravity="center"
android:longClickable="false"
android:paddingBottom="1dip"
android:paddingTop="1dip"
android:text="sample"
android:textColor="#ff7f1d"
android:textSize="17dip"
android:textStyle="bold" />
<TextView
android:id="@+id/list_content2"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_margin="5dip"
android:clickable="false"
android:gravity="center"
android:linksClickable="false"
android:longClickable="false"
android:paddingBottom="1dip"
android:paddingTop="1dip"
android:text="sample"
android:textColor="#6d6d6d"
android:textSize="17dip" />
</LinearLayout>
</LinearLayout>
Lo que hago en este momento es que estoy agregando el encabezado como un objeto de lista normal, pero me gustaría que fuera como encabezado y, en mi caso, tenga una fecha.
Tengo este código en mi xml para el encabezado:
<TextView
style="?android:attr/listSeparatorTextViewStyle"
android:id="@+id/separator"
android:text="Header"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#757678"
android:textColor="#f5c227" />
e intenté ocultarlo cuando no es necesario y mostrarlo cuando era necesario, pero simplemente estropeé el resto del código. Intenté algunos tutoriales más pero también tuvieron el mismo efecto.
¿Alguien podría guiarme sobre cómo hacerlo de esa manera fácil?

Probablemente esté buscando un ExpandableListView que tenga encabezados (grupos) para separar elementos (elementos secundarios).
Buen tutorial sobre el tema: aquí .
fuente
onGroupClickque solo maneja el clic en "encabezados" y no necesita deshabilitar el clic o algo así, simplemente cancele cualquier acción de colapso y configure todos los grupos para expandirse desde el inicio.ExpandableListViewes lo mejor en la mayoría de los casos. Sin embargo, tengo una situación en la que quiero mostrar una lista plana a veces, y una lista con encabezados en otras ocasiones en mi Actividad. Lamentablemente, laExpandableListAdapterinterfaz no extiende laListAdapterinterfaz, por lo que para el polimorfismo me veo obligado a usar la solución de @ antew.Como alternativa, hay una bonita biblioteca de terceros diseñada solo para este caso de uso. Por lo tanto, debe generar encabezados basados en los datos que se almacenan en el adaptador. Se llaman adaptadores Rolodex y se usan con
ExpandableListViews. Se pueden personalizar fácilmente para comportarse como una lista normal con encabezados.Usar los
Eventobjetos del OP y saber que los encabezados se basan en loDateasociado con él ... el código se vería así:La actividad
El adaptador
fuente
Lo que hice para hacer la Fecha (por ejemplo, 01 de diciembre de 2016) como encabezado. Usé la biblioteca StickyHeaderListView
https://github.com/emilsjolander/StickyListHeaders
Convierta la fecha a larga en milis [no incluya la hora] y conviértala como el ID del encabezado.
fuente
Aquí hay un proyecto de muestra , basado en la respuesta detallada y útil de antew, que implementa un
ListViewcon múltiples encabezados que incorpora titulares de vista para mejorar el rendimiento de desplazamiento.En este proyecto, los objetos representados en el
ListViewson instancias de la claseHeaderItemo la claseRowItem, los cuales son subclases de la clase abstractaItem. Cada subclase deItemcorresponde a un diferente tipo de vista en el adaptador personalizado,ItemAdapter. El métodogetView()enItemAdapterdelega la creación de la vista para cada elemento de la lista a ungetView()método individualizado en cualquieraHeaderItemoRowItem, dependiendo de laItemsubclase utilizada en la posición pasada algetView()método en el adaptador. CadaItemsubclase proporciona su propio soporte de vista.Los titulares de la vista se implementan de la siguiente manera. Los
getView()métodos en lasItemsubclases verifican si elViewobjeto que se pasó algetView()métodoItemAdapteres nulo. Si es así, se infla el diseño apropiado y se crea una instancia de un objeto titular de la vista y se asocia con la vista inflada medianteView.setTag(). Si elViewobjeto no es nulo, entonces un objeto titular de la vista ya estaba asociado con la vista, y el titular de la vista se recupera medianteView.getTag(). La forma en que se utilizan los titulares de la vista se puede ver en el siguiente fragmento de código deHeaderItem:La implementación completa de ListView sigue. Aquí está el código Java:
También hay dos diseños de elementos de lista, uno para cada subclase de elementos. Aquí está el diseño
header, utilizado por HeaderItem:Y aquí está el diseño
row, utilizado por RowItem:Aquí hay una imagen de una parte del ListView resultante:
fuente