[Tutoriel] : Android ListView personnalisée [ +Recherche ]

Article par Zied Rebhi:


Bienvenue à tous , dans cet article on va voir comment personnaliser une ListView.
La ListView peut comporter plusieurs types de données : Images , Textes etc.
Dans ce tutoriel on va vous montrer comment on crée une ListView avec des images et textes .
On  prend comme exemple : une application pour un restaurant (Food & Drinks).


Notre application va afficher des aliments avec leurs images , leurs noms et leurs prix .Donc un aliment (Food) est caractérisé par : 
  • name: String
  • price: float
  • picture: Drawable (Image)
==> Besoin d'une classe Food (objet)

import android.graphics.drawable.Drawable;

public class Food {
 int id;
 String name;
 Drawable picture;
 float price;

 public Food(int id, String name, Drawable picture, float price) {
  super();
  this.id = id;
  this.name = name;
  this.picture = picture;
  this.price = price;
 }

 public Food() {
  super();
 }

 public int getId() {
  return id;
 }

 public void setId(int id) {
  this.id = id;
 }

 public String getName() {
  return name;
 }

 public void setName(String name) {
  this.name = name;
 }

 public Drawable getPicture() {
  return picture;
 }

 public void setPicture(Drawable picture) {
  this.picture = picture;
 }

 public float getPrice() {
  return price;
 }

 public void setPrice(float price) {
  this.price = price;
 }

 @Override
 public String toString() {
  return "Food [id=" + id + ", name=" + name + ", picture=" + picture
    + ", price=" + price + "]";
 }

}



Pour afficher les listes des aliments on va créer ajouter une ListView à notre layout activity_main, et pour ajouter la fonction du recherche on ajouter un EditText: activity_main.xml :

 < LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/LinearLayout1"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    < EditText
        android:id="@+id/search"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:ems="10"
        android:hint="Search something.." />
        
    < /EditText>

    < ListView
        android:id="@+id/listFood"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
   < /ListView >

< /LinearLayout>

Maintenant , pour qu'on puisse bien afficher la liste des informations on veut , on va presenter comment une ligne de la liste sera affiché dans la ListView, pour cela  on crée un  fichier xml sous /layout: food_row.xml :

 < RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal"
    android:padding="5dip" >

    < LinearLayout
        android:id="@+id/thumbnail"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_marginRight="5dip"
        android:padding="3dip" &amp;gt;

        &amp;lt; ImageView
            android:id="@+id/picture"
            android:layout_width="50dip"
            android:layout_height="50dip" />
    < / LinearLayout >

    < TextView
        android:id="@+id/name"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerVertical="true"
        android:layout_toLeftOf="@+id/price"
        android:layout_toRightOf="@+id/thumbnail"
        android:text="name"
        android:textColor="#040404"
        android:textSize="15dip"
        android:textStyle="bold"
        android:typeface="sans" />

    < TextView
        android:id="@+id/price"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:layout_centerVertical="true"
        android:layout_marginRight="14dp"
        android:gravity="right"
        android:text="price"
        android:textColor="#ea5178"
        android:textSize="10dip"
        android:textStyle="bold" />

< / RelativeLayout>


Passons à la programmation java alors , on a déja ecrit la classe Food pour les objets , maintenant on va créer un adaptateur pour afficher les données convenablement dans la ListView: On crée une classe "FoodListAdapter" qui étend de la classe "BaseAdapter" :
public class FoodListAdapter extends BaseAdapter {

 private List listFood = null;
 LayoutInflater layoutInflater;

 // constructeur
 public FoodListAdapter(Context context, List listFood) {
  this.listFood = listFood;
  layoutInflater = LayoutInflater.from(context);
  this.listFood = listFood;

 }

 @Override
 public int getCount() {
  // TODO Auto-generated method stub
  return listFood.size();
 }

 @Override
 public Object getItem(int position) {
  // TODO Auto-generated method stub
  return listFood.get(position);
 }

 @Override
 public long getItemId(int arg0) {
  // TODO Auto-generated method stub
  return arg0;
 }

 static class ViewHolder {
  TextView nomView;
  TextView priceView;
  ImageView pictureView;

 }

 @Override
 public View getView(int position, View convertView, ViewGroup parent) {
  ViewHolder holder;

  if (convertView == null) {
   convertView = layoutInflater.inflate(R.layout.food_row, null);
   holder = new ViewHolder();
   // initialisation des vues
   holder.nomView = (TextView) convertView.findViewById(R.id.name);
   holder.priceView = (TextView) convertView
                                        .findViewById(R.id.price);
   holder.pictureView = (ImageView) convertView
     .findViewById(R.id.picture);

   convertView.setTag(holder);
  } else {
   holder = (ViewHolder) convertView.getTag();
  }
  // affchier les données convenablement dans leurs positions
  holder.nomView.setText(listFood.get(position).getName());
  holder.priceView.setText(String.valueOf(listFood.get(position)
    .getPrice()) + " $");
  holder.pictureView.setBackgroundDrawable(listFood.get(position)
    .getPicture());
  return convertView;

 }
}

Passons à notre activity :Toute est prét !
On va initialiser une liste avec des objets de type Food , pour cela on a besoin:
  • Drawable[] listPictures: des images des aliments (ajoutées dans le dossier /drawable) téléchargeable ici
https://www.mediafire.com/?3ypo4awt3hm3t73
Télécharger les Images

  • Float[] listPrices: liste des prix
  • String[] listNames: liste des noms à ajouter
Voici la liste des variables globales qu'on va les utiliser :
 String[] listNames = { "Cake", "Cheese", "Chicken", "Cocktail", "Coffe",
   "Coffe black", "Humberger", "IceCream", "Pizza", "Sandwich",
   "Soupe", "Yaghurt" };

 Float[] listPrices = { (float) 1.5, (float) 1.4, (float) 4.3, (float) 1.8,
   (float) 0.7, (float) 0.650, (float) 1.7, (float) 1.200,
   (float) 4.500, (float) 2.500, (float) 2.8, (float) 0.500 };

 ArrayList listFood;
 ListView lv;
 EditText search;


Pour la fonction du recherche et filtrage on va ajouter une fonction filtrer () qu'on l'appelle lorsque il y a un changement dans l'EditText : "addTextChangedListener":


 public void filtrer() {
  // retourner la chaine saisie par l'utilisateur
  String name = search.getText().toString();
  // créer une nouvelle liste qui va contenir la résultat à afficher
  ArrayList listFoodNew = new ArrayList();
  
  for (Food food : listFood) {
   // si le nom du food commence par la chaine saisie , ajouter-le !
   if (food.getName().toLowerCase().toString().startsWith(name)) {
    listFoodNew.add(food);
   }
  }
  //vider la liste
  lv.setAdapter(null);
  // ajouter la nouvelle liste
  lv.setAdapter(new FoodListAdapter(getApplicationContext(), listFoodNew));
 }

Le code finale de notre activité sera :
@Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);

  setContentView(R.layout.activity_food);
  lv = (ListView) findViewById(R.id.listFood);
  search = (EditText) findViewById(R.id.search);
  Drawable[] listPictures = {
    getResources().getDrawable(R.drawable.cake),
    getResources().getDrawable(R.drawable.cheese),
    getResources().getDrawable(R.drawable.chicken),
    getResources().getDrawable(R.drawable.cocktail),
    getResources().getDrawable(R.drawable.coffe),
    getResources().getDrawable(R.drawable.coffeblack),
    getResources().getDrawable(R.drawable.hamburger),
    getResources().getDrawable(R.drawable.icecream),
    getResources().getDrawable(R.drawable.pizza),
    getResources().getDrawable(R.drawable.sandwich),
    getResources().getDrawable(R.drawable.soup),
    getResources().getDrawable(R.drawable.yoghurt) };

  listFood = new ArrayList();

  for (int i = 0; i &amp;lt; listPictures.length; i++) {
   listFood.add(new Food(i + 1, listNames[i], listPictures[i],
     listPrices[i]));
  }

  lv.setAdapter(new FoodListAdapter(getApplicationContext(), listFood));
  search.addTextChangedListener(new TextWatcher() {

   @Override
   public void onTextChanged(CharSequence arg0, int arg1, int arg2,
     int arg3) {
    // TODO Auto-generated method stub

   }

   @Override
   public void beforeTextChanged(CharSequence arg0, int arg1,
     int arg2, int arg3) {
    // TODO Auto-generated method stub

   }

   @Override
   public void afterTextChanged(Editable arg0) {
    // TODO Auto-generated method stub
    filtrer();
   }
  });

 }

On obtient comme résultat :




Pour le code finale , il est disponible sur mediafire:


Vous avez aimé cet article ? alors suivez-nous sur Twitter, Google+ et Facebook, et partagez-le avec les boutons ci-dessous ! Vos commentaires sont les bienvenus.

Enregistrer un commentaire