Tenho ListView que contém alguns tipos de eventos. Os eventos são classificados por dia, e eu gostaria de ter um cabeçalho com a data para todos os dias e, em seguida, ouvir os eventos abaixo.
Aqui está como eu preencho essa 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);
e é assim que minha classe TwoText se parece:
public class TwoText {
public String classID;
public String state;
public TwoText(String classID, String state) {
this.classID = classID;
this.state = state;
}
}
e é assim que minha classe TwoTextArrayAdapter se parece:
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;
}
}
e este é 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>
o que eu faço no momento é que estou adicionando cabeçalho apenas como um objeto de lista regular, mas gostaria que fosse como cabeçalho e, no meu caso, tivesse uma data nele.
Eu tenho este código em meu xml para cabeçalho:
<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 tentei escondê-lo quando não era necessário e mostrá-lo quando necessário, mas acabei bagunçando o resto do meu código. Tentei mais alguns tutoriais, mas eles também tiveram o mesmo efeito.
Alguém poderia me orientar sobre como fazer dessa maneira fácil?
Você provavelmente está procurando por uma ExpandableListView que tem cabeçalhos (grupos) para separar itens (filhos).
Bom tutorial sobre o assunto: aqui .
fonte
onGroupClick
que só trata o clique em "cabeçalhos" e você não precisa desabilitar o clique ou algo assim, apenas cancele qualquer ação de recolhimento e configure todos os grupos para expandidos desde o início.ExpandableListView
é melhor na maioria dos casos. No entanto, tenho uma situação em que às vezes desejo exibir uma lista simples e outras vezes uma lista com cabeçalhos em minha atividade. Infelizmente, aExpandableListAdapter
interface não estende aListAdapter
interface, por isso, para polimorfismo, sou forçado a usar a solução de @ antew.Como alternativa, há uma ótima biblioteca de terceiros projetada apenas para esse caso de uso. Por meio do qual você precisa gerar cabeçalhos com base nos dados armazenados no adaptador. Eles são chamados de adaptadores Rolodex e são usados com
ExpandableListViews
. Eles podem ser facilmente personalizados para se comportarem como uma lista normal com cabeçalhos.Usar os
Event
objetos do OP e conhecer os cabeçalhos são baseados noDate
associados a ele ... o código seria mais ou menos assim:A atividade
O adaptador
fonte
O que fiz para tornar a data (por exemplo, 01 de dezembro de 2016) como cabeçalho. Usei a biblioteca StickyHeaderListView
https://github.com/emilsjolander/StickyListHeaders
Converta a data para longa em milis [não inclua a hora] e torne-a como o ID do cabeçalho.
fonte
Aqui está um projeto de amostra , com base na resposta detalhada e útil de antew, que implementa um
ListView
com vários cabeçalhos que incorpora suportes de visualização para melhorar o desempenho de rolagem.Neste projeto, os objetos representados no
ListView
são instâncias da classeHeaderItem
ou da classeRowItem
, ambas as quais são subclasses da classe abstrataItem
. Cada subclasse deItem
corresponde a um tipo de visualização diferente no adaptador personalizadoItemAdapter
. O métodogetView()
emItemAdapter
delega a criação da visualização de cada item da lista para umgetView()
método individualizado emHeaderItem
ouRowItem
, dependendo daItem
subclasse usada na posição passada para ogetView()
método no adaptador. CadaItem
subclasse fornece seu próprio portador de visualização.Os detentores de visualização são implementados da seguinte maneira. Os
getView()
métodos nasItem
subclasses verificam se oView
objeto que foi passado para ogetView()
método emItemAdapter
é nulo. Nesse caso, o layout apropriado é inflado e um objeto de suporte de visualização é instanciado e associado à visualização inflada viaView.setTag()
. Se oView
objeto não for nulo, então um objeto de portador de visão já estava associado à visão, e o portador de visão é recuperado viaView.getTag()
. A forma como os suportes de visualização são usados pode ser vista no seguinte snippet de códigoHeaderItem
:A implementação completa do ListView segue. Aqui está o código Java:
Existem também dois layouts de item de lista, um para cada subclasse de item. Aqui está o layout
header
, usado por HeaderItem:E aqui está o layout
row
, usado por RowItem:Aqui está uma imagem de uma parte do ListView resultante:
fonte