Dans ce tuto je vais réaliser une listview avec des entêtes intercalées pour créer des catégories . L’affichage que je veux obtenir
La Technique que je vais utilisée ici c’est de créer ma propre class ListSeparer qui est une extension de la class BaseAdapter qui elle pourra contenir d’autre adapter .
Je créer deux attributs sections et headers, section tableau de string et header tableau de string et adapter.
Je reprogramme certaine méthode exemple getItem celle qui donne la position dans ma listview par rapport au sections ajoutées
D’abord mes fichiers xml.
Le fichier list_header.xml pour afficher les entetes
1 2 3 4 5 6 7 8 9 10 11 | <?xml version="1.0" encoding="utf-8"?>
<!-- list_header.xml -->
<TextView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/list_header_title"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:paddingTop="2dip"
android:paddingBottom="2dip"
android:paddingLeft="5dip"
style="?android:attr/listSeparatorTextViewStyle" /> |
Le fichier list_item.xml pour des items simples
1 2 3 4 5 6 7 8 9 10 11 12 | <?xml version="1.0" encoding="utf-8"?>
<!-- list_item.xml -->
<TextView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/list_item_title"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:paddingTop="10dip"
android:paddingBottom="10dip"
android:paddingLeft="15dip"
android:textAppearance="?android:attr/textAppearanceLarge"
/> |
Le fichier list_complex.xml pour des items avec titres et sous titres
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | <?xml version="1.0" encoding="utf-8"?>
<!-- list_complex.xml -->
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingTop="10dip"
android:paddingBottom="10dip"
android:paddingLeft="15dip"
>
<TextView
android:id="@+id/list_complex_title"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
/>
<TextView
android:id="@+id/list_complex_caption"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceSmall" />
</LinearLayout> |
Ma class ListSeparer.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 | public class ListSeparer extends BaseAdapter {
public final Map<String,Adapter> sections = new LinkedHashMap<String,Adapter>();
public final ArrayAdapter<String> headers;
public final static int TYPE_SECTION_HEADER = 0;
public ListSeparer(Context context) {
//pour les entetes j'utilise le fichier list_header.xml
headers = new ArrayAdapter<String>(context, R.layout.list_header);
}
//méthode pour ajouter dans le header le nom de ma catégorie et dans sections le nom et un objet adapter
public void addSection(String section, Adapter adapter) {
this.headers.add(section);
this.sections.put(section, adapter);
}
//Renvoi la position d'un clique
public Object getItem(int position) {
for(Object section : this.sections.keySet()) {
Adapter adapter = sections.get(section);
int size = adapter.getCount() + 1;
// récupération de la position dans la section
if(position == 0) return section;
if(position < size) return adapter.getItem(position - 1);
// passe à la section suivant
position -= size;
}
return null;
}
// renvoi le nombre d'item
public int getCount() {
// total de l'ensemble des sections, plus une pour chaque tête de section
int total = 0;
for(Adapter adapter : this.sections.values())
total += adapter.getCount() + 1;
return total;
}
public int getViewTypeCount() {
int total = 1;
for(Adapter adapter : this.sections.values())
total += adapter.getViewTypeCount();
return total;
}
public int getItemViewType(int position) {
int type = 1;
for(Object section : this.sections.keySet()) {
Adapter adapter = sections.get(section);
int size = adapter.getCount() + 1;
// Récupération de la position dans la section
if(position == 0) return TYPE_SECTION_HEADER;
if(position < size) return type + adapter.getItemViewType(position - 1);
// passe a la section suivante moins un par l'entête
position -= size;
type += adapter.getViewTypeCount();
}
return -1;
}
public boolean areAllItemsSelectable() {
return false;
}
public boolean isEnabled(int position) {
return (getItemViewType(position) != TYPE_SECTION_HEADER);
}
public View getView(int position, View convertView, ViewGroup parent) {
int sectionnum = 0;
for(Object section : this.sections.keySet()) {
Adapter adapter = sections.get(section);
int size = adapter.getCount() + 1;
// Récupération de la position dans la section
if(position == 0) return headers.getView(sectionnum, convertView, parent);
if(position < size) return adapter.getView(position - 1, convertView, parent);
// otherwise jump into next section
position -= size;
sectionnum++;
}
return null;
}
public long getItemId(int position) {
return position;
}
} |
Exemple d’utilisation de ma classe dans une application.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | public class ListeCourse extends Activity{
public final static String ITEM_TITLE = "title";
public final static String ITEM_CAPTION = "caption";
LecteurFlux objLectFlux = new LecteurFlux();
public Map<String,?> createItem(String title, String caption) {
Map<String,String> item = new HashMap<String,String>();
item.put(ITEM_TITLE, title);
item.put(ITEM_CAPTION, caption);
return item;
}
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
List<Map<String,?>> security = new LinkedList<Map<String,?>>();
security.add(createItem("titre 1 ", "sous titre du titre1"));
security.add(createItem("titre 2", "Sous titre du titre 2"));
security.add(createItem("Titre 3", "sous titre du titre 3 un peu lon pour avoir un retour à la ligne"));
// creation de nom objet de type ListSeparer
ListSeparer adapter = new ListSeparer(this);
// ajoute d'un objet adapter nom de la catégorie Array Test avec deux items first item et item two
adapter.addSection("Array test", new ArrayAdapter<String>(this, R.layout.list_item, new String[] { "First item", "item two" }));
//ajout d'un autre adapter avec entete plux complex et des items sur deux lignes
adapter.addSection("Plus complex", new SimpleAdapter(this, security, R.layout.list_complex,
new String[] { ITEM_TITLE, ITEM_CAPTION }, new int[] { R.id.list_complex_title, R.id.list_complex_caption }));
ListSeparer adapter = objLectFlux.liste_course_periode(this);
ListView list = new ListView(this);
list.setAdapter(adapter);
this.setContentView(list);
}
} |
Il est temps de mettre à profit les tutoriels d’Android France:
Passez à la vitesse supérieure et investissez quelques dizaines d’euros pour acquérir les connaissances qui vous feront gagner de l’argent avec vos applications rendez-vous sur notre boutique Android-france pour ces formations en vidéo
Suite à vos mails j’ai créé deux nouvelles catégories pour accéder directement aux tuto.
- Developpez sous Android pour tous les tuto sur les étapes du développement du logiciel de gestion de recette
- Tuto développement les autres tuto de développement sur des thèmes précis



















20 septembre 2009 à 19 h 11 min
“LecteurFlux objLectFlux = new LecteurFlux();”
je comprends pas trop le délire là lol
Info pour les autres, virer ces lignes :
- LecteurFlux objLectFlux = new LecteurFlux(); (début de fichier)
- ListSeparer adapter = objLectFlux.liste_course_periode(this); (fin de fichier)
J’apprécie beaucoup tous les tutos, mais celui ci n’est vraiment pas clair du tout. Il s’adresse à des débutants (dont je fais parti) et j’avoue que ca a été chaud de mettre en oeuvre.
Je pense également que le minimum serait de vérifier que le tuto fonctionne correctement … Il manque les dépendances et des lignes en trop dont on ne sait même pas d’où elles sortent.
Merci tout de même
20 septembre 2009 à 20 h 33 min
@TeChn4K: LecteurFlux objLectFlux = new LecteurFlux(); ce sont les restes d’un autre programme. Pour les dépendances petite astuce sur eclipse il faut appuyer ctrl+alt+o et automatiquement toutes les dépendances seront incluses
01 novembre 2009 à 15 h 46 min
So, what should I do with the LecteurFlux class? How to implement it?
Regards,
Alessio
01 novembre 2009 à 16 h 16 min
Ok, solved… the entire tutorial has been translated from http://jsharkey.org/blog/2008/08/18/separating-lists-with-headers-in-android-09/, and the LecteurFlux class has been added without showing where this class comes from. Anyway in the original source, everything is well documented.
22 septembre 2010 à 15 h 38 min
Tuto bien utile, dommage pour les lignes en trop quand même !