ADAPTER (PERSONNALISÉ)
1
LISTVIEW DE PERSONNES
q On peut « peupler » les Spiner (et ListView) en utilisant un string-
array dans strings.xml
q Lorsqu’on ne connait pas à l’avance les lignes à afficher, on peut
« peupler » les Spiner (et ListView) en utilisation une collection de
String et un Adapter
q Lorsqu’il ne suffit pas d’afficher un String par ligne d’un Spiner ou
d’un ListView, on peut personnaliser son propre Adapter
2
LISTVIEW DE PERSONNES
On veut une app qui affiche des étudiants
q L’app dispose d’une ListView
q Chaque élement (personne) est composé de plusieurs widget
q Un TextView (name)
q un RatingBar (rank)
q Une ImageView (picture)
q Chaque élément de la liste est cliquable
3
LISTVIEW
q Présentation de l’application
Comment procéder ?
Ø Créer la Vue principale contenant la ListView
Ø Créer une classe pour un Item (ici Studient)
Ø Créer l’interface Clickable
Ø MainActivity implémente Clickable (ajouter la/les
méthodes à surcharger)
Ø Créer la vue pour chaque item (ici studient_layout)
Ø Ecrire l’adapter personnalisé qui étend BaseAdapter
Ø Réaliser l’affichage dans MainActivity
Ø Prépare d’une collection à afficher
Ø Crée un Adapter en lui donnant la collection et this pour callback
Ø Adapter la ListView à la collection
Ø Surcharge des méthodes de Clickable
4
CRÉER UNE CLASSE POUR UN ITEM
(ICI STUDIENT)
public class Studient {
private String name;
private float rank;
private int picture;
public Studient(String name, float rank, int picture) {
this.name = name;
this.rank = rank;
this.picture = picture;
}
public String getName() {
return name;
}
public float getRank() {
return rank;
}
public void setRank(float rank) {
this.rank = rank;
}
public int getPicture() {
return picture;
}
}
5
CRÉER LA VUE PRINCIPALE
CONTENANT LA LISTVIEW
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:gravity="center_horizontal"
tools:context=".MainActivity">
<TextView
android:id="@+id/label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="ListView d'étudiants"
android:textSize="34sp" />
<ListView
android:id="@+id/listView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="20dp »/>
</LinearLayout>
6
CRÉER L’INTERFACE CLICKABLE
Le context servira à l’adapter
qui aura besoin de savoir
dans quelle vue
public interface Clickable { (activity_main par exemple)
void onClicItem(int itemIndex); afficher les éléments
Context getContext();
}
Rien n’interdit de
rajouter des
méthodes si besoin
J
7
MAINACTIVITY IMPLÉMENTE CLICKABLE
public class MainActivity extends AppCompatActivity implements Clickable{
@Override
protected void onCreate(Bundle savedInstanceState) {… }
@Override
public void onClicItem(int itemIndex) {
//for exemple...
Toast.makeText(getApplicationContext(),"item "+itemIndex+" cliqué", Toast.LENGTH_LONG).show();
}
@Override
public Context getContext() {
return getApplicationContext();
} Le context servira à
} l’adapter qui aura besoin de
savoir dans quelle vue
(activity_main par exemple)
afficher les éléments
8
CRÉER LA VUE POUR CHAQUE ITEM
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="@+id/picture"
android:layout_width="90dp"
android:layout_height="90dp"
android:src="@drawable/rallo" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="20dp" <RatingBar
android:gravity="center_horizontal" android:id="@+id/rank"
android:orientation="vertical"> android:layout_width="wrap_content"
android:layout_height="wrap_content"
<TextView android:scaleX="0.5"
android:id="@+id/name" android:scaleY="0.5"
android:layout_width="wrap_content" android:numStars="4"
android:layout_height="wrap_content" android:layout_weight="5" />
android:layout_weight="1" </LinearLayout>
android:textSize="24sp"
android:text="name" /> </LinearLayout>
REMARQUE: on peut utiliser n’importe quel Layout 9
ECRIRE L’ADAPTER PERSONNALISÉ
QUI ÉTEND BASEADAPTER
@Override
public class StudientAdapter extends BaseAdapter { public View getView(int position, View convertView, ViewGroup parent) {
private final List<Studient> items; View layoutItem;
private final LayoutInflater mInflater; //(1) : Réutilisation des layouts (lorsque c'est possible)
layoutItem = (convertView == null
private final Clickable callBackActivity;
? mInflater.inflate(R.layout.studient_layout, parent, false)
: convertView);
public StudientAdapter(List<Studient> items, MainActivity
callBackActivity) { //(2) : Récupération des éléments
this.items = items; TextView name = layoutItem.findViewById(R.id.name);
this.callBackActivity = callBackActivity; ImageView picture = layoutItem.findViewById(R.id.picture);
mInflater = LayoutInflater.from(callBackActivity.getContext()); RatingBar ratingBar = layoutItem.findViewById(R.id.rank);
}
//(3) : Mise à jour des valeurs
public int getCount() { name.setText(items.get(position).getName());
return items.size(); picture.setImageResource(items.get(position).getPicture());
ratingBar.setRating(items.get(position).getRank());
}
public Object getItem(int position) { //(4) écouteur sur chaque élément de l'adapter
return items.get(position); layoutItem.setOnClickListener( click -> callBackActivity.onClicItem(position));
}
public long getItemId(int position) { //On retourne l'item créé.
return position; return layoutItem;
} }
}
10
RÉALISER L’AFFICHAGE DANS
MAINACTIVITY
public class MainActivity extends AppCompatActivity implements Clickable{
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ListView listview = findViewById(R.id.listView);
//(1) préparation de la collection
List<Studient> studients = new ArrayList<>();
studients.add( new Studient("rallo",3.6f,R.drawable.rallo) );
studients.add( new Studient("luffy",5.0f,R.drawable.luffy) );
studients.add( new Studient("yoda",3.6f,R.drawable.yoda) );
studients.add( new Studient("sacha",3.6f,R.drawable.pokemon) );
//(2) Création et initialisation de l'Adapter (+ abonnement listener pour lorsqu'on cliquera)
StudientAdapter adapter = new StudientAdapter(studients, this);
//(3) adapter la ListView à la collection
listview.setAdapter(adapter);
}
…
}
11
Pour aller plus loin…
…et si le contenu de la ListView a changé (par exemple
on a modifié une valeur depuis la RatingBar)…
à il faut faire un écouteur sur la RatingBar
à Il faut modifier les données en conséquence
à Il faut notifier l’adapter du changement
public void onRatingBarChange(int itemIndex, float value) {
items.get(itemIndex).setValue(value);
adapter.notifyDataSetChanged();
}
12