• Intercaler des entêtes dans une listview

    Publié le 27 juillet 2009 par Guy (GuyTouch)


    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

    listviewcomplex 192x300 Intercaler des entêtes  dans une listview Android France

    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

    ?Download download.txt
    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

    ?Download download.txt
    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

    ?Download download.txt
    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.

    ?Download download.txt
    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.

    ?Download download.txt
    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.


    Guy

    Co-fondateur du site Android france, senior lead developper, passionné de bière et de cigare cubain

    Twitter Google+ 

  • 5 Commentaires pour ce billet

    1. 1 - TeChn4K dit:

      “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 ;)

    2. 2 - Guy dit:

      @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

    3. 3 - BiGAlex dit:

      So, what should I do with the LecteurFlux class? How to implement it?

      Regards,
      Alessio

    4. 4 - BiGAlex dit:

      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.

    5. 5 - Lebzul dit:

      Tuto bien utile, dommage pour les lignes en trop quand même !

  • Laissez un commentaire

  • Les Brèves