Introduction
Nous allons dans cet exercice créer une vue en liste sous Android, encore appelée ListView. Pour ce faire nous allons modifier l’activité d’une application Android en liste d’activité (classe ListActivity). Chaque ligne de la liste sera composée d’une image et d’un texte.
Nous utiliserons aussi le pattern adaptateur d’Android pour remplir la liste. Ce dernier est utilisé dans toute l’architecture Android pour remplir des listes : Il est donc indispensable d’en connaître son fonctionnement.
Nous utiliserons ici la version 4.3 du SDK Android, ainsi que l’IDE Eclipse ADT.
Voici l’application finale que nous allons obtenir :
Lien pour obtenir les images de l’exercices : images
Liste des étapes à réaliser :
1) Création d’un projet Android avec une activité simple
2) Modification de l’activité de notre projet en liste d’activité
+ Intégration dans le projet d’un Layout personnalisé pour décrire une ligne de notre liste : ici un texte et une image (voir ci-dessus)
4) Ajout des images dans le projet (png ou jpg)
5) Création d’un adaptateur personnalisé Android qui retournera chaque ligne de la liste
6) Implémentation de la sélection d’un élément de la liste
Création d’un projet Android avec une activité simple
Créez un projet Android comme décrit ci-dessous :
Voici les 4 écrans de création de projet qui se suivent.
Le projet à ce stade doit être crée et propose un Hello World classique !
Modification de l’activité de notre projet en liste d’activité
Nous allons modifier le source de notre activité pour la transformer en liste d’activité. Il est nécessaire de faire hériter notre activité java de la classe Android ListActivity.
Créez le layout suivant (ici rowlayout.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="wrap_content" > <ImageView android:contentDescription="row" android:id="@+id/icon" android:layout_width="60dp" android:layout_height="60dp" android:layout_marginLeft="6dp" android:layout_marginRight="6dp" android:layout_marginTop="5dp" android:layout_marginBottom="5dp" android:src="@drawable/ic_launcher" > </ImageView> <TextView android:id="@+id/label" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_marginTop="20dp" android:layout_marginBottom="20dp" android:layout_marginLeft="10dp" android:text="text" android:textSize="26sp" > </TextView> </LinearLayout>
Le layout ci-dessus contient une image et un texte (ImageView + TextView). Il représentera le modèle d’un élément de la liste, c’est à dire le modèle d’une ligne.
Modifiez le source java comme ci-dessous :
public class MainActivity extends ListActivity { @Overrided protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); String[] values = new String[] { "Device", "Géo localisation", "Accéléromètre", "Navigateur internet", "Dialogues", "Album photos", "Connexion réseau", "Gestion des fichiers", "Carnet de contacts" }; ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.rowlayout, values); setListAdapter(adapter); }
Après avoir modifié le projet comme indiqué ci-dessus, nous obtiendrons une liste avec les textes précisés dans le source de l’activité ainsi que l’icône par défaut présente dans notre application.
Ajout des images dans le projet
Il faut maintenant ajouter les images que nous voulons afficher dans notre liste.
Avec Eclipse il est possible de copier (drag and drop) directement les images dans le projet. Pour ce faire nous créerons dans le projet un répertoire drawable dans les ressources.
Création d’un adaptateur personnalisé
Android utilise des adaptateurs pour remplir les listes. Nous allons ici créer un adaptateur sous forme d’une classe Java. Ce dernier retournera à la liste d’activité chaque ligne à afficher.
Voici le code de cet adaptateur :
public class MonAdaptateurDeListe extends ArrayAdapter<String> { private Integer[] tab_images_pour_la_liste = { R.drawable.device, R.drawable.geolocation, R.drawable.accelerometer, R.drawable.navigateur_internet, R.drawable.notifications, R.drawable.album_photo, R.drawable.connection_network, R.drawable.files, R.drawable.carnet_contact }; @Override public View getView(int position, View convertView, ViewGroup parent) { LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE); View rowView = inflater.inflate(R.layout.rowlayout, parent, false); TextView textView = (TextView) rowView.findViewById(R.id.label); ImageView imageView = (ImageView) rowView.findViewById(R.id.icon); textView.setText(getItem(position)); if(convertView == null ) imageView.setImageResource(tab_images_pour_la_liste[position]); else rowView = (View)convertView; return rowView; } public MonAdaptateurDeListe(Context context, String[] values) { super(context, R.layout.rowlayout, values); } }
Il faut maintenant que notre activité utilisé cette adaptateur. Nous avons besoin de modifier son code comme ci-dessous :
public class MainActivity extends ListActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); String[] values = new String[] { "Device", "Géo localisation", "Accéléromètre", "Navigateur internet", "Dialogues", "Album photos", "Connexion réseau", "Gestion des fichiers", "Carnet de contacts" }; MonAdaptateurDeListe adaptateur = new MonAdaptateurDeListe(this, values); setListAdapter(adaptateur); } }
On voit clairement ci-dessus que l’adaptateur utilisé sera désormais le nôtre. La méthode setListAdapter(..) permet de fixer sur la liste d’activités notre objet adaptateur.
Implémentation de la sélection d’un élément de la liste
Il nous reste à intercepter le touch sur un élément de la liste. C’est assez simple puisque la liste d’activités propose un événement pour ce faire. Il suffit de créer la fonction dans notre activité.
public class MainActivity extends ListActivity { //... @Override protected void onListItemClick(ListView l, View v, int position, long id) { Toast.makeText(this, "Position : " + position, Toast.LENGTH_LONG).show(); } }
Et voilà le tour est joué, notre liste intercepte les événements.
Autre exemple de code de l’adaptateur de liste :
package com.ltm.ltmlistview; import android.content.Context; import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.ImageView; import android.widget.TextView; public class MonAdaptateurDeListe extends BaseAdapter { @Override public long getItemId(int position) { Log.v("ltm","getItemId("+position+")="); return tab_images_pour_la_liste[position]; } @Override public Object getItem(int position) { Log.v("ltm","getItem("+position+")"); return position; } @Override public int getCount() { // TODO Auto-generated method stub Log.v("ltm","getCount()"); return tab_images_pour_la_liste.length; } private Integer[] tab_images_pour_la_liste = { R.drawable.device, R.drawable.geolocation, R.drawable.accelerometer, R.drawable.navigateur_internet, R.drawable.notifications, R.drawable.album_photo, R.drawable.connection_network, R.drawable.files, R.drawable.carnet_contact }; String[] values = new String[] { "Device", "Géo localisation", "Accéléromètre", "Navigateur internet", "Dialogues", "Album photos", "Connexion réseau", "Gestion des fichiers", "Carnet de contacts" }; Context _context; @Override public View getView(int position, View convertView, ViewGroup parent) { LayoutInflater inflater = (LayoutInflater) _context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); View rowView = inflater.inflate(R.layout.rowlayout, parent, false); //if( convertView == null ) { TextView textView = (TextView) rowView.findViewById(R.id.label); ImageView imageView = (ImageView) rowView.findViewById(R.id.icon); textView.setText(values[position]); imageView.setImageResource(tab_images_pour_la_liste[position]); /*}else { rowView = (View)convertView; }*/ Log.v("ltm", "Position = " + position); return rowView; } public MonAdaptateurDeListe(Context context) { super(); _context = context; } }
J’espère que cet exercice vous a servi et plus, n’hésitez-pas à le partager en cliquant les boutons ci-dessous.
Merci,pour ce formidable tuto
je suis arriver a la deuxieme etape mais seulement dans le main.activity, rowlayout est souligner en rouge , que dois-je faire?
Si dans votre IDE le code est souligné en rouge c’est qu’il ne peut compiler. Dans la colonne de gauche ou en mettant votre souris sur la ligne, l’IDE doit vous indiquer l’erreur.
écrit juste R.layout.rowlayout au lieu de android.R.layout.rowlayout
ok
Vraiment merci pour ce tuto. Il m’a été d’une grande utilité.
L’apprentissage de la programmation Android n’est pas chose simple. Le pattern « Adapter » est vraiment important. Bon courage.
merci pour ce merveilleux tuto…mais j’ai une question, comment faire pour afficher les resultats d’une requetes mysql et traduit par Json dans un listview? ma table contient les colonnes : math, francais, anglais et je veux qu’apres la recherche le resultat de math s’affiche sur un le premier item du Listview, le resultat de francais sur le second item du Listview etc… comment faire cela, sachant que tout marche deja bien et que c’est juste à ce niveau là que je suis bloqué. car actuellement tous les resultats s’affichent que sur un seul item du listview. merci pour votre aide
Le meilleur pattern (widget) pour afficher une matrice (lignes + colonnes) est d’utiliser un GridView. Ce dernier s’alimente aussi grâce un adaptateur (Adapter).
super
Merci ! j’ai cherché pendant longtemps un tuto clair sur ce sujet et là je vous dis BRAVO !