J'ai ListView qui contient des événements. Les événements sont triés par jour, et j'aimerais avoir un en-tête avec la date pour chaque jour, puis les événements écoutent ci-dessous.
Voici comment je remplis cette liste:
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);
et voici à quoi ressemble ma classe TwoText:
public class TwoText {
public String classID;
public String state;
public TwoText(String classID, String state) {
this.classID = classID;
this.state = state;
}
}
et voici à quoi ressemble ma classe 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;
}
}
et c'est 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>
ce que je fais pour le moment, c'est que j'ajoute un en-tête comme un objet de liste normal, mais j'aimerais que ce soit comme en-tête et dans mon cas avoir une date dessus.
J'ai ce code dans mon xml pour l'en-tête:
<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" />
et j'ai essayé de le cacher quand c'était inutile et de le montrer quand nécessaire mais j'ai juste foiré le reste de mon code. J'ai essayé quelques tutoriels supplémentaires mais ils ont également eu le même effet.
Quelqu'un pourrait-il me guider sur la façon de procéder facilement?
Vous recherchez probablement un ExpandableListView qui a des en-têtes (groupes) pour séparer les éléments (enfants).
Joli tutoriel sur le sujet: ici .
la source
onGroupClick
qui ne gère que les clics sur les "en-têtes" et vous n'avez pas besoin de désactiver le clic ou quelque chose comme ça, annulez simplement toute action de réduction et définissez tous les groupes en expansion depuis le début.ExpandableListView
c'est mieux dans la plupart des cas. Cependant, j'ai une situation où je veux parfois afficher une liste plate et une liste avec des en-têtes à d'autres moments de mon activité. Malheureusement, l'ExpandableListAdapter
interface n'étend pas l'ListAdapter
interface, donc pour le polymorphisme, je suis obligé d'utiliser la solution de @ antew.Au lieu de cela, il existe une belle bibliothèque tierce conçue spécialement pour ce cas d'utilisation. Dans lequel vous devez générer des en-têtes en fonction des données stockées dans l'adaptateur. Ils sont appelés adaptateurs Rolodex et sont utilisés avec
ExpandableListViews
. Ils peuvent facilement être personnalisés pour se comporter comme une liste normale avec des en-têtes.En utilisant les
Event
objets de l'OP et en sachant que les en-têtes sont basés sur ceux qui lui sontDate
associés ... le code ressemblerait à ceci:L'activité
L'adaptateur
la source
Ce que j'ai fait pour faire de la date (par exemple le 01 décembre 2016) comme en-tête. J'ai utilisé la bibliothèque StickyHeaderListView
https://github.com/emilsjolander/StickyListHeaders
Convertissez la date en millisecondes [n'incluez pas l'heure] et faites-en l'ID d'en-tête.
la source
Voici un exemple de projet , basé sur la réponse détaillée et utile d'Antew, qui implémente un
ListView
avec plusieurs en-têtes qui incorpore des détenteurs de vue pour améliorer les performances de défilement.Dans ce projet, les objets représentés dans
ListView
sont des instances de la classeHeaderItem
ou de la classeRowItem
, qui sont toutes deux des sous-classes de la classe abstraiteItem
. Chaque sous - classe deItem
correspond à un type d'affichage différent dans l'adaptateur personnalisé,ItemAdapter
. La méthodegetView()
surItemAdapter
délègue la création de la vue pour chaque élément de liste à unegetView()
méthode individualisée surHeaderItem
ouRowItem
, selon laItem
sous - classe utilisée à la position transmise à lagetView()
méthode sur l'adaptateur. ChaqueItem
sous-classe fournit son propre support de vue.Les détenteurs de vue sont implémentés comme suit. Les
getView()
méthodes desItem
sous - classes vérifient si l'View
objet qui a été passé à lagetView()
méthode surItemAdapter
est nul. Si tel est le cas, la disposition appropriée est gonflée et un objet de support de vue est instancié et associé à la vue gonflée viaView.setTag()
. Si l'View
objet n'est pas nul, alors un objet de support de vue était déjà associé à la vue et le support de vue est récupéré viaView.getTag()
. La façon dont les détenteurs de vue sont utilisés peut être vue dans l'extrait de code suivant deHeaderItem
:La mise en œuvre complète de ListView suit. Voici le code Java:
Il existe également deux présentations d'éléments de liste, une pour chaque sous-classe d'éléments. Voici la disposition
header
, utilisée par HeaderItem:Et voici la disposition
row
, utilisée par RowItem:Voici une image d'une partie de la ListView résultante:
la source