Créer une ListView avec des contrôles CheckBox et gérer les événements sur ces derniers

L'application que je vous propose est assez classique et simple. Il s'agit de créer une liste comportant des checkbox. Au clic d'une checkbox, ceci va faire changer la couleur de fond du bloc de celle-ci. Attention: suite à quelque bogue sur ce tutoriel, je vous informe que ce tutoriel fonctionne seulement si la hauteur de la ListView ne dépasse pas la hauteur de l'écran (il ne faut pas avoir de scroll). Une solution est de créer une pagination pour passer à la suite de la liste.
13 commentaires Donner une note à l'article (4.5)

Article lu   fois.

L'auteur

Profil ProSite personnel

Liens sociaux

Viadeo Twitter Facebook Share on Google+   

I. Introduction

Voici des captures d'écran de l'application :

screenshot1 screenshot2 screenshot3


Les technologies utilisées dans ce tutoriel sont :
- listView ;
- listActivity ;
- événement sur checkbox ;
- adaptateur.

II. Création de l'application

Pour cela nous allons commencer par créer une application :

projet

III. Les vues

Commençons par les vues.
La première est le main.xml. Elle comprend la listView (la liste). Sachant que nous allons utiliser une ListActivity par la suite, l'identifiant de la listView sera @android:id/list. Ce qui permettra à l'activité de reconnaitre automatiquement la liste.
Voici le code de la vue qui est assez simple :

main.xml
Sélectionnez

<?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">
	
	<ListView android:id="@android:id/list" android:layout_width="fill_parent"
		android:layout_height="fill_parent" />

</LinearLayout>


La deuxième vue, nommée list_detail.xml, correspond au contenu de chaque ligne de la liste. Dans notre exemple, nous avons en tout quatre champs texte (deux libellés et deux champs modifiables) et une checkbox. Les champs texte sont placés dans des tableaux afin de pouvoir les intégrer correctement avec la checkbox. Mais là, libre à vous de placer vos champs où vous voulez !
Pour la checkbox, nous définissons la fonction qui permettra de récupérer l'événement dans l'activité comme ceci android:onClick="MyHandler". L'identifiant de la checkbox est check, celle du champ modifiable contenant le nom est nom et celui du prénom est prenom.
Pour une raison ergonomique, nous choisissons de colorer une partie du bloc. Cette partie est celle définie par l'identifiant blocCheck.
Voici le code :

list_detail.xml
Sélectionnez

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
	android:orientation="horizontal" android:layout_width="fill_parent"
	android:layout_height="wrap_content">

	<!-- Tableau permettant d'afficher tout le contenu d'un bloc -->
	<TableLayout android:id="@+id/blocCheck" 
		android:background="@color/blue"
		android:layout_height="wrap_content" 
		android:layout_width="fill_parent"
		android:layout_marginTop="25px"
		android:layout_marginBottom="25px">

		<!-- La première ligne affiche deux libellés côte à côte (le nom et sa valeur) -->
		<TableRow android:layout_width="fill_parent"
			android:layout_height="wrap_content" 
			android:paddingLeft="4sp"
			android:paddingBottom="4sp">
			<LinearLayout
				android:orientation="horizontal" 
				android:layout_width="fill_parent"
				android:layout_height="wrap_content" 
				android:paddingLeft="20sp"
				android:layout_weight="1" 
				android:layout_gravity="center_vertical">

				<TextView android:layout_width="wrap_content"
					android:layout_height="wrap_content" 
					android:textSize="20sp"
					android:text="@string/nom" 
					android:layout_gravity="left"
					android:layout_marginRight="5sp" />
				<TextView android:id="@+id/nom" 
					android:layout_width="wrap_content"
					android:layout_height="wrap_content" 
					android:textSize="20sp"
					android:layout_gravity="left" />
			</LinearLayout>
		</TableRow>
		
		<!-- Cette ligne affiche les deux libellés du prénom et la checkbox -->
		<TableRow android:layout_width="fill_parent"
			android:layout_height="wrap_content" 
			android:paddingLeft="4sp"
			android:baselineAligned="true">
			<LinearLayout
				android:orientation="horizontal" 
				android:layout_width="fill_parent"
				android:layout_height="wrap_content" 
				android:paddingLeft="20sp"
				android:layout_weight="1" 
				android:layout_gravity="center_vertical">
				<TextView android:layout_width="wrap_content"
					android:layout_height="wrap_content" 
					android:textSize="20sp"
					android:text="@string/prenom" 
					android:layout_gravity="left"
					android:layout_marginRight="5sp" />
				<TextView android:id="@+id/prenom" 
					android:layout_width="wrap_content"
					android:layout_height="wrap_content" 
					android:textSize="20sp"
					android:layout_gravity="left" />
			</LinearLayout>
			<CheckBox android:layout_height="wrap_content" 
				android:id="@+id/check"
				android:layout_width="wrap_content" 
				android:layout_gravity="right"
				android:layout_marginRight="10sp" 
				android:onClick="MyHandler"/>
		</TableRow>
	</TableLayout>
</LinearLayout>

Les vues sont créées.

IV. Les paramètres

Comme vous avez pu le remarquer, nous utilisons des variables définies dans d'autres fichiers xml afin de pouvoir internationaliser notre application si nous le souhaitons. Ainsi, nous avons un fichier string.xml comportant les différents libellés utilisés comme ceci :

string.xml
Sélectionnez


<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="hello">Hello World, checkBoxListVue!</string>
    <string name="app_name">CheckBox list</string>
    <string name="nom">Nom : </string>
    <string name="prenom">Prénom : </string>
</resources>

De même, nous allons utiliser des couleurs. Donc afin de pouvoir les modifier facilement et aussi de pouvoir les utiliser convenablement nous créons un fichier color.xml comme ceci :

color.xml
Sélectionnez


<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="blue">#3050A0</color>
    <color name="green">#006600</color>
</resources>

V. L'activité

Écrivons maintenant l'activité.
Cette activité remplit ma liste et utilise un adaptateur redéfini par une classe écrite plus bas. Elle contient la fonction publique void MyHandler(View v) qui permet de récupérer l'événement du clic sur la checkbox (rappelez-vous, nous avons défini cette fonction dans la vue au niveau de la checkbox).
Voici le code commenté de l'activité :

checkBoxListVue.java
Sélectionnez

package com.developpez.vue;

import java.util.ArrayList;
import java.util.HashMap;
import android.app.ListActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.CheckBox;
import android.widget.ListView;

public class checkBoxListVue extends ListActivity {
    private ListView list;
	
	/** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        //Récupération automatique de la liste (l'id de cette liste est nommé obligatoirement @android:id/list afin d'être détecté)
		list = getListView();
        
		// Création de la ArrayList qui nous permettra de remplir la listView
		ArrayList<HashMap<String, String>> listItem = new ArrayList<HashMap<String, String>>();

		// On déclare la HashMap qui contiendra les informations pour un item
		HashMap<String, String> map;

		map = new HashMap<String, String>();
		map.put("nom", "Mouse");
		map.put("prenom", "Mickey");
		listItem.add(map);

		map = new HashMap<String, String>();
		map.put("nom", "Bunny");
		map.put("prenom", "Bugs");
		listItem.add(map);

		//Utilisation de notre adaptateur qui se chargera de placer les valeurs de notre liste automatiquement et d'affecter un tag à nos checkbox

		MyListAdapter mSchedule = new MyListAdapter(this.getBaseContext(), listItem,
				R.layout.list_detail, new String[] { "nom", "prenom" }, new int[] {
						R.id.nom, R.id.prenom });

		// On attribue à notre listView l'adaptateur que l'on vient de créer
		list.setAdapter(mSchedule);
    }
    
    //Fonction appelée au clic d'une des checkbox
	public void MyHandler(View v) {
		CheckBox cb = (CheckBox) v;
		//on récupère la position à l'aide du tag défini dans la classe MyListAdapter
		int position = Integer.parseInt(cb.getTag().toString());
		
		// On récupère l'élément sur lequel on va changer la couleur
		View o = list.getChildAt(position).findViewById(
				R.id.blocCheck);

		//On change la couleur
		if (cb.isChecked()) {
			o.setBackgroundResource(R.color.green);
		} else {
			o.setBackgroundResource(R.color.blue);
		}
	}
}

VI. L'adaptateur

Il ne reste plus qu'à définir la classe MyListAdaptater qui permettra surtout de définir un tag pour chaque checkbox. Ce tag correspond à la position du bloc (l'item) dans lequel est située la checkbox. Ceci est défini dans la fonction getView.
Voici le code commenté :

MyListAdaptater.java
Sélectionnez

package com.developpez.vue;

import java.util.List;
import java.util.Map;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CheckBox;
import android.widget.SimpleAdapter;

public class MyListAdapter extends SimpleAdapter
{
	private LayoutInflater	mInflater;

	public MyListAdapter (Context context, List<? extends Map<String, ?>> data,
			int resource, String[] from, int[] to)
	{
		super (context, data, resource, from, to);
		mInflater = LayoutInflater.from (context);

	}

	@Override
	public Object getItem (int position)
	{
		return super.getItem (position);
	}

	@Override
	public View getView (int position, View convertView, ViewGroup parent)
	{
		//Ce test permet de ne pas reconstruire la vue si elle est déjà créée
		if (convertView == null)
		{
			// On récupère les éléments de notre vue
			convertView = mInflater.inflate (R.layout.list_detail, null);
			// On récupère notre checkBox
			CheckBox cb = (CheckBox) convertView.findViewById (R.id.check);
			// On lui affecte un tag comportant la position de l'item afin de
			// pouvoir le récupérer au clic de la checkbox
			cb.setTag (position);
		}
		return super.getView (position, convertView, parent);
	}

}

VII. Conclusion

Et voilà, votre application est terminée ! Vous pouvez désormais créer des listes et contrôler les événements liés aux éléments situés à l'intérieur de celle-ci.
Merci d'avoir suivi ce tutoriel et à bientôt ;)

VIII. Remerciements

Je tiens à remercier Feanorin, Viish, Jpelaho pour les améliorations apportées à ce tutoriel et ClaudeLELOUP pour la relecture.

Vous avez aimé ce tutoriel ? Alors partagez-le en cliquant sur les boutons suivants : Viadeo Twitter Facebook Share on Google+   

  

Les sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright © 2011 developpez Developpez LLC. Tous droits réservés Developpez LLC. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez LLC. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.