Mam ListView, który zawiera jakieś zdarzenia. Zdarzenia są sortowane według dni i chciałbym mieć nagłówek z datą na każdy dzień, a następnie słuchaj wydarzeń poniżej.
Oto jak zapełniam tę listę:
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);
a tak wygląda moja klasa TwoText:
public class TwoText {
public String classID;
public String state;
public TwoText(String classID, String state) {
this.classID = classID;
this.state = state;
}
}
a tak wygląda moja klasa 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;
}
}
a to jest 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>
w tej chwili dodaję nagłówek jako zwykły obiekt listy, ale chciałbym, aby był to nagłówek iw moim przypadku miał na nim datę.
Mam ten kod w moim XML dla nagłówka:
<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" />
i próbowałem go ukryć, gdy jest niepotrzebny i pokazać go, gdy jest to konieczne, ale po prostu zepsułem resztę kodu. Wypróbowałem jeszcze kilka samouczków, ale również dały ten sam efekt.
Czy ktoś mógłby mnie pokierować, jak to zrobić w ten łatwy sposób?
Prawdopodobnie szukasz ExpandableListView, który ma nagłówki (grupy) oddzielające elementy (elementy podrzędne).
Niezły tutorial na ten temat: tutaj .
źródło
onGroupClick
obsługuje tylko kliknięcie "nagłówków" i nie musisz wyłączać kliknięcia lub czegoś podobnego, po prostu anuluj każdą akcję zwijania i ustaw wszystkie grupy na rozwinięte od początku.ExpandableListView
w większości przypadków jest to najlepsze. Jednak mam sytuację, w której czasami chcę wyświetlić płaską listę, a czasami listę z nagłówkami w moim działaniu. NiestetyExpandableListAdapter
interfejs nie rozszerzaListAdapter
interfejsu, więc w przypadku polimorfizmu jestem zmuszony użyć rozwiązania @ antew.Alternatywnie istnieje przyjemna biblioteka innej firmy zaprojektowana specjalnie dla tego przypadku użycia. Przy czym musisz wygenerować nagłówki na podstawie danych przechowywanych w adapterze. Nazywa się je adapterami Rolodex i są używane z
ExpandableListViews
. Można je łatwo dostosować, aby zachowywały się jak zwykła lista z nagłówkami.Używając
Event
obiektów OP i wiedząc, że nagłówki są oparte naDate
skojarzonym z nim ... kod wyglądałby mniej więcej tak:Aktywność
Adapter
źródło
Co zrobiłem, aby Data (np. 1 grudnia 2016 r.) Była nagłówkiem. Użyłem biblioteki StickyHeaderListView
https://github.com/emilsjolander/StickyListHeaders
Zamień datę na długą w milisach [nie uwzględniaj godziny] i ustaw ją jako identyfikator nagłówka.
źródło
Oto przykładowy projekt , oparty na szczegółowej i pomocnej odpowiedzi Antew, który implementuje a
ListView
z wieloma nagłówkami, który zawiera uchwyty widoku w celu poprawy wydajności przewijania.W tym projekcie obiekty reprezentowane w programie
ListView
są instancjami klasyHeaderItem
lub klasyRowItem
, z których obie są podklasami klasy abstrakcyjnejItem
. Każda podklasaItem
odpowiada innemu typowi widoku w niestandardowym adapterzeItemAdapter
. MetodagetView()
onItemAdapter
deleguje tworzenie widoku dla każdego elementu listy do zindywidualizowanejgetView()
metody na jednejHeaderItem
lubRowItem
, w zależności odItem
podklasy używanej w pozycji przekazanej dogetView()
metody w adapterze. KażdyItem
podklasa zapewnia własny uchwyt widoku.Uchwyty widoku są realizowane w następujący sposób. Te
getView()
metody naItem
podklasy sprawdzić, czyView
obiekt, który został przekazany dogetView()
metody naItemAdapter
to null. Jeśli tak, odpowiedni układ jest zawyżany, a obiekt uchwytu widoku jest tworzony i powiązany z rozszerzonym widokiem za pośrednictwemView.setTag()
. JeśliView
obiekt nie jest pusty, wówczas obiekt posiadacza widoku był już skojarzony z widokiem, a uchwyt widoku jest pobierany za pośrednictwemView.getTag()
. Sposób, w jaki są używane uchwyty widoku, można zobaczyć w poniższym fragmencie kodu zHeaderItem
:Następuje pełna implementacja ListView. Oto kod Java:
Istnieją również dwa układy elementów listy, po jednym dla każdej podklasy Element. Oto układ
header
używany przez HeaderItem:A oto układ
row
używany przez RowItem:Oto obraz części wynikowego ListView:
źródło