680 likes | 820 Views
Android ListView, ListActivity une introduction. jean-michel Douin, douin au cnam point fr version : 28 Mars 2013. Notes de cours. Sommaire. Vue ListView Présentation Adapter la Vue d’une liste d’items aux souhaits du programmeur Le patron Stratégie
E N D
Android ListView, ListActivity une introduction jean-michel Douin, douin au cnam point fr version : 28 Mars 2013 Notes de cours
Sommaire • Vue • ListView • Présentation • Adapter la Vue d’une liste d’items aux souhaits du programmeur • Le patron Stratégie • Utiliser des stratégies d’affichage standard • Installer sa propre stratégie • Accès aux ressources décrites en XML • Optimiser ces accès (cache), recyclage • Filtrage, tri • Contrôleur • View / Activity • OnItemClickListener, onItemClick • ListView / ListActivity • onListItemClick • onItemLongClick Technique … • Chargement d’une liste et AsyncTask
Bibliographie utilisée http://developer.android.com/resources/index.html Le cours de Victor Matos http://grail.cba.csuohio.edu/~matos/notes/cis-493/Android-Syllabus.pdf http://www.vogella.com/android.html Plusieurs livres Android A Programmers Guide - McGraw Hill Professional Android Application Development – Wrox Le livre de Mark Murphy - Pearson Une vidéo youtube Google IO the world of ListView par Romain Guy http://www.youtube.com/watch?v=wDBM6wVEO70
Présentation d’une liste d’items • Un composant graphique commun • À un grand nombre d’applications
Item de la liste • Chaque item de la liste est une View • Un texte par Item soit LinearLayout +TextView (standard, prédéfini) • Une Image, Un titre, un nombre LinearLayout + TableRow + ImageView + TextView Défini par l’application
ListView Vue • Une liste de vues présentant des items • Chaque item s’affiche selon un format, • Format défini en XML, • Un adaptateur se charge de l’affichage, • Un style de présentation, une stratégie d’affichage, est choisie • Il existe des stratégies standard • Une liste d’items constituée de noms séparés d’un trait, • ArrayAdapter • Une liste d’items constituée d’une grille, • SimpleAdapter, • Une liste d’items, reflet d’une interrogation dans une base de données • CursorAdapter • Des adaptateurs créés par le programmeur • BaseAdapter est la classe toute prête qu’ il suffira de dériver
Vue, Contrôleur et Modèle • Vue La vue de la liste et sa stratégie d’affichage • Les items s’affichent selon une stratégie • Standard, prédéfinie • Style de présentation, stratégie d’affichage définie par l’utilisateur • setAdapter • Contrôleur Les interactions avec l’utilisateur • A chaque clic sur l’un des items une action est déclenchée • Une action est déclenchée, un menu apparaît… • onItemClickListener et ListView, Activity • onListItemClick au sein d’une ListActivity • Modèle La liste des objets Java représente le modèle • List<Item>, Item[], toute collection (une classe Java,…) • Tout changement d’état du modèle sera notifié à la vue • Adéquation Vue/Modèle prise en charge par Android • getAdapter().notifyDataSetChanged();
Vue, style d’affichage • Vue La vue de la liste et sa stratégie d’affichage • Les items s’affichent selon une stratégie • setAdapter • Standard, prédéfinie • Style de présentation, stratégie d’affichage définie par l’utilisateur • Patron Strategy • Usage classique : Layout en Swing • http://best-practice-software-engineering.ifs.tuwien.ac.at/patterns/strategy.html • Un rappel en quatre diapositives
Le patron stratégie, l’original • Strategy • Une interface commune • ConcreteStrategy • Quelle stratégie effective ? • Context • Utilisation d’une stratégie choisie par le client, à la configuration • http://www.dofactory.com/Patterns/PatternStrategy.aspx
Le patron stratégie, l’original • Strategy • Une interface commune pour tous les affichages • Android : ListAdapter • ConcreteStrategy • Quelle stratégie pour quel rendu ? • Android : ArrayAdapter, SimpleAdapter, CursorAdapter, BaseAdapter, MonAdaptateur, MaStratégieDAffichage … • Context • Utilisation d’une stratégie choisie par le client • Android : ListView
Un exemple : Usage du patron Strategy Le patron Strategy / API Android Classe Strategy / android.widget.Adapter Classe ConcreteStrategy / android.widget.ArrayAdapter • Son usage (ici simplifié) avec le nom des classes des API Android
Adapter, ListAdapter android.widget.ArrayAdapter est une stratégie concrète toute prête Dans laquelle ces 3 méthodes sont implémentées, pour chaque item getCount, le nombre d’items getItem, l’item à cette position getView, la vue de cet item
Adapter, ListAdapter + ListView ListView liste = (ListView)findViewById(R.id.liste); liste.setAdapter(new ArrayAdapter ( ….
Un premier exemple et son affichage • La ListView est décrite en XML • Le fichier res/layout/liste.xml • Avec une stratégie prédéfinie • setAdapter( new ArrayAdapter<String>(contexte, Ressource_XML_Prédéfinie,String[] modèle • Une Activity • Un affichage • setContentView • Un modèle • Un diplôme Cnam constitué de plusieurs unités d’enseignement • NFP121, NSY102, RSX116, SMB116, SMB117, UARS01 • String[] ou List<String>
Le fichier res/layout/liste.xml La ListView est décrite en XML • La liste est un composant graphique, son identifiant R.id.listeId
Une activity, onCreate, affectation de la Vue • Redéfinition de la méthode onCreate • Cumul du comportement • Affectation de la Vue (res/layout/liste.xml) • setContentView • lv référence le composant graphique • findViewById
Une activity, le modèle • Le modèle itemsCC : • items d’un certificat de compétences constitué de 6 unités • NFP121, RSX116, NSY102, SMB116, SMB117, UARS01 • Unités enseignées au Cnam (présentiel et à distance) • Certificat de compétences intégrateur applications mobiles • String[] itemsCC = …
Une activity, choix de la stratégie d’affichage • Stratégie : lv.setAdapter( new ArrayAdapter<String>( • Choix de la stratégie standard d’affichage • this , le contexte • android.R.layout.simple_list_item_1, un texte par ligne, prédéfini • itemsCC, le modèle
Exécution, le rendu • Le rendu ici un item constitué d’un texte par ligne
Une activity, choix de la stratégie d’affichage • Le rendu : un item par liste • android.R.layout.simple_list_1 est prédéfini • Serait-ce un TextView ?
android.R.simple_list_item_1 • Un item de la liste est décrit ainsi • Standard … • <android-sdk>/platforms/<android-version>/data/res/layout/simple_list_item_1.xml
http://developer.android.com/reference/android/R.html • D’autres prédéfinis existent
Sommaire-suite • Vue • ListView • Présentation • Adapter la Vue d’une liste d’items aux souhaits du programmeur • Le patron Stratégie • Utiliser des stratégies d’affichage standard • Installer sa propre stratégie • Accès aux ressources décrites en XML • Optimiser ces accès (cache), recyclage • Filtrage, tri • Contrôleur • View/Activity • onItemClick, OnItemClickListener • ListView/ListActivity • onListItemClick • onItemLongClick Technique … • Chargement d’une liste et AsyncTask
Un deuxième exemple L’exemple précédent s’est enrichi • Ajoutons pour chaque item • Une image pour la période d’enseignement • 1er ou 2ème semestre • Le lieu d’enseignement en présentiel • Prévoir que ce lieu puisse changer…
Description xml, d’un item Chaque item de la liste contient : • L’intitulé de l’unité • Une image suivie du lieu d’enseignement • Le fichier res/layout/uecnam.xml • Décrit complètement cet item
Description xml, d’une ligne Chaque ligne contient : • L’intitulé de l’unité • TextView • Une image suivie du lieu d’enseignement
Description xml, d’une ligne Chaque ligne contient : • L’intitulé de l’unité • Une image suivie du lieu d’enseignement • ImageView suivie TextView
Le rendu attendu • Stratégie à créer, il faut donc écrire notre propre Adapter • Notons que seules 5 unités, items, sont affichés ici • Android a déclenché les 5 affichages correspondants • 5 appels de getView, getItem,… de la stratégie choisie
Proposons maintenant notre propre Adapter • Selon le patron Strategy, • Une classe implémentant l’interface ListAdapter Aidons nous de l’existant … • Il existe une sous classe qu’il suffit de dériver • BaseAdapter • Il suffira de définir getCount, getItem, getItemId et getView • Nous l’appellerons UECnamAdapter • Notre modèle a évolué • Ce n’est plus une simple table d’intitulés • NFP121, RSX116, NSY102, SMB116, SMB117, UARS01
Notre modèle a évolué • Diplôme, UE deviennent des objets métiers • Un diplôme est constitué d’unités d’enseignement (UE) • Chaque diplôme • possède un intitulé et • délivre une liste de ses UE qui le compose List<UE> getListe() • Une UE est constituée • d’un intitulé, • String getNom() • du lieu d’enseignement et • String getLieu() • de la période • String getPeriode() Diplôme UE
L’activité ne change guère, tjs quelques lignes Proposons une stratégie concrète • UECnamAdapter • Il ne nous reste plus qu’à définir les méthodes • getCount, getItem, getItemId et getView
La classe UECnamAdapter • Une stratégie concrète d’affichage des items • UECnamAdapter hérite de BaseAdapter • Tout diplôme propose la liste des unités qui le compose • getCount, getItem, getItemId sont immédiats
La classe UECnamAdapter, méthode getView • Cette méthode est appelée par Android • À chaque affichage de la liste et seulement sur les lignes présentées • Notre exemple présente 5 unités sur 6 • 5 appels de getView • getView la méthode
La classe UECnamAdapter, méthode getView • Pour chaque Item, nous avons • getView algorithme : • Allons chercher le fichier XML défini pour l’UE (uecnam.xml) • Réalisons l’adéquation • ListView / Modèle • Ligne de la liste / UE du diplôme • Affectons les items de chaque View avec certains attributs de l’UE
Identifiants et affectation des champs • Les identifiants issus du fichier XML • nomId • ImageId • lieuId
La méthode getView Allons chercher le fichier XML défini pour l’UE (res/layout/uecnam.xml) • LayoutInflater lecture du fichier XML • Création de l’arbre Java • Inflate( le fichier XML, la racine, booléen (complétion d’un arbre existant)
La méthode getView • Réalisons l’adéquation • ListView / Modèle • Item de la liste / UE du diplôme • Affectons les items de chaque View avec certains attributs de l’UE
Prohibitif en temps d’exécution ! • Inflate transforme à la volée le fichier XML en arbre Java • En version naïve cette transformation se produit à chaque appel • A chaque manipulation de l’utilisateur • A chaque affichage dans la partie visible de la liste • … • Performance en temps d’exécution? Idée : • Le système pourrait avoir déjà créé la vue, devenue invisible … et pourrait tenter un recyclage
Recyclage, performances • Source http://lucasr.org/2012/04/05/performance-tips-for-androids-listview/
Recyclage de la vue d’un item • Optimisation • Le système a déjà créé la vue, dont il a conservé une référence • il tente un recyclage en transmettant cette référence • La référence est transmise à la méthode getView • Un contrat est en place • Si le paramètre convertView == null, la vue doit être créée • Alors les liens sur les vues de la ligne sont conservées dans un cache • Cache géré par le programmeur • Sinon une référence de la vue est transmise et peut donc être utilisée • Nous utiliserons alors les éléments du cache
Gestion du cache d’un item, déclaration • Une classe interne et statique au sein de UECnamAdapter • Ce cache d’un item constitué d’une instance de CacheView • Cette instance est conservée dans un champ (tag) de la Vue de l’item • itemView.setTag (new CacheView(…) • Interne et statique sera préférée, attention aux classes internes et membres qui conservent une référence de l’instance englobante, référence engendrant parfois des fuites mémoires
Gestion du cache, le contrat • getView • alors • la vue doit être créée • les références sur les vues de l’item sont installées dans un cache • sinon • les références sont extraites du cache
Initialisation du cache (convertView == null) • Le champ tag d’une vue permet de mémoriser une référence
C’est du recyclage, convertView != null • Le champ tag d’une vue permet de mémoriser une référence (Ici le cache entre deux affichages) • Le cache est utilisé
Tri, filtrage • La classe Adapter s’en charge • Ou bien le modèle propose ce type de méthodes • Ordre alphabétique des UE • Ordre en fonction de la période (1er ou 2ème semestre) • Etc..
En exemple de tri, ici selon le nom et la période • Il suffit de proposer, selon les critères retenus • Une implémentation de l’interface Comparator entre deux UE • Java tradition, cf. java.util.Collections
Sommaire • Vue • ListView • Présentation • Adapter la Vue d’une liste d’items aux souhaits du programmeur • Le patron Stratégie • Utiliser des stratégies d’affichage standard • Installer sa propre stratégie • Accès aux ressources décrites en XML • Optimiser ces accès (cache), recyclage • Filtrage, tri • Contrôleur • Le modèle a changé • View / Activity • onItemClick, OnItemClickListener • ListView / ListActivity • onListItemClick • onItemLongClick Technique … • Chargement d’une liste et AsyncTask
Le lieu d’enseignement change … • Ce qui peut arriver, le modèle change • La vue est prévenue …. • Changement du modèle • RSX116 est maintenant programmé en studio d’enregistrement en 17 2 6 • Appel du mutateur, changement de lieu • Appel de la méthode de l’adapter • ((BaseAdapter)lv.getAdapter()).notifyDataSetChanged(); • Adéquation par Android du modèle et de la vue Réactualisation, appel(s) automatique(s) de getView
Activity versus ListActivity • Activity • Déclaration d’une ListView dans un fichier, recherche par l’identifiant • ListView lv = (ListView) findViewById(R.id.liste) • Affectation de la stratégie d’affichage • lv.setAdapter(new UeCnamAdapter( … • Affectation des écouteurs, aux items de la liste par le programme • En général des instances de classes internes et membres • Pour chaque item de la liste, une instance d’une classe • implements OnItemClickListener • ListActivity • La déclaration est implicite • Il doit exister une liste dont l’Id est @android:id/list • Affectation de la stratégie d’affichage, par une méthode • setListAdapter(new UECnamAdapter( … • Affectation des écouteurs implicite • Il suffit de redéfinir la méthode onListItemClick, redéfinie de la classe ListActivity • Alors ListActivity nous préférerons
Une classe dédiée ListActivity • usage des ListView par une sous classe d’Activity : ListActivity • res/layout/liste.xml contient une ListView avec cet Id @android:id/list liste.xml La liste doit avoir cet identifiant ListeActivity