7 – Créez une vue en liste (ListView) avec texte + image

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 :

Exercice sur les vues en liste

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.

Ecran 1 de création du projet

Ecran2

Ecran 3

Ecran 4

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.

Projet listview

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.

Catégories
11 Comments
  1. Yannick

    je suis arriver a la deuxieme etape mais seulement dans le main.activity, rowlayout est souligner en rouge , que dois-je faire?

  2. Khevin Kita

    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

0 Pings & Trackbacks

Laisser un commentaire