Télécharger la présentation
Publié parJérôme Beau Modifié depuis plus de 9 années
1
Android ListView, ListActivity une introduction
jean-michel Douin, douin au cnam point fr version : 10 Novembre 2014 Notes de cours
2
Sommaire Vue Contrôleur MVC
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, ect. Contrôleur View / Activity OnItemClickListener, onItemClick ListView / ListActivity onListItemClick onItemLongClick MVC Une proposition Annexe : technique, chargement d’une liste et AsyncTask
3
Bibliographie utilisée
Le cours de Victor Matos 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
4
Présentation d’une liste d’items
Un composant graphique commun À un grand nombre d’applications
5
Item de la liste Chaque item de la liste est une View
Une Image, Un titre, un nombre par item LinearLayout + TableRow + ImageView + TextView Défini par l’application, un fichier XML Un texte par Item LinearLayout +TextView (standard, prédéfini)
6
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
7
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 getListAdapter().notifyDataSetChanged();
8
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 Un rappel en quatre diapositives
9
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
10
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
11
Un exemple : Usage du patron Strategy
android.widget 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
12
Adapter, ListAdapter android.widget.ArrayAdapter est une stratégie concrète toute prête Dans laquelle ces 3 méthodes sont implémentées, et ce pour chaque item getCount, le nombre d’items getItem, l’item à cette position getView, la vue de cet item
13
Adapter, ListAdapter + ListView
Installation de la stratégie par setAdapter ListView liste = (ListView)findViewById(R.id.liste); liste.setAdapter(new ArrayAdapter ( ….
14
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>
15
Le fichier res/layout/liste.xml
La ListView est décrite en XML La liste est un composant graphique, son identifiant R.id.listeId
16
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
17
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 = …
18
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
19
Exécution, le rendu Le rendu ici un item constitué d’un texte par ligne
20
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 ?
21
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
22
D’autres prédéfinis existent
23
Sommaire-suite Vue Contrôleur Technique …
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
24
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…
25
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
26
Description xml, d’une ligne
Chaque ligne contient : L’intitulé de l’unité TextView Une image suivie du lieu d’enseignement
27
Description xml, d’une ligne
Chaque ligne contient : L’intitulé de l’unité Une image suivie du lieu d’enseignement ImageView suivie TextView
28
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 Donc 5 appels de getView, getItem,… de la stratégie choisie
29
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
30
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() Une instance du diplôme toute prête: DiplomeCnam.CCY114 DiplômeCnam UE
31
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
32
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
33
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
34
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
35
Identifiants et affectation des champs
Les identifiants issus du fichier XML nomId ImageId lieuId
36
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)
37
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
38
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
39
Recyclage, performances
Source
40
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 Le cache est 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
41
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
42
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
43
Initialisation du cache (convertView == null)
Le champ tag d’une vue permet de mémoriser une référence
44
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) convertView != null Le cache est utilisé
45
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..
46
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
47
Sommaire Contrôleur Vue Le modèle a changé ListView / Activity
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é ListView / Activity onItemClick, OnItemClickListener ListView / ListActivity onListItemClick onItemLongClick Technique … Chargement d’une liste et AsyncTask
48
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 Appel du mutateur, changement de lieu… La Vue doit être actualisée Appel de la méthode de l’adapter ((BaseAdapter)lv.getAdapter()).notifyDataSetChanged(); Ou si ListActivity ((BaseAdapter)getListAdapter()).notifyDataSetChanged(); Adéquation par Android du modèle et de la vue Réactualisation, appel(s) automatique(s) de getView
49
Activity versus ListActivity
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 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
50
Une classe dédiée ListActivity
usage des ListView par une sous classe d’Activity : ListActivity res/layout/liste.xml contient (au moins) une ListView avec cet Id @android:id/list Android.R.list Identifiant imposé ListActivity
51
Contrôleur, ListActivity
Au clic, contextuel A chaque clic un toast est présenté, l’URL de l’UE est affiché À terme le site de l’unité pourrait être affiché … Méthode onListItemClick, redéfinie de la classe ListActivity
52
A chaque clic, un Toast est affiché
Ici un clic sur RSX116 affiche l’URL de l’unité Une deuxième activité pourrait être exécutée Par exemple une WebView …
53
Contrôleur, Activity et OnItemClickListener
ListView et Activity Une implémentation de OnItemClickListener
54
Sommaire Vue Contrôleur Technique … 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 Chaque chargement d’item est en tâche de fond et utilise AsyncTask
55
Rappel : schéma de programme, syntaxe, AsyncTask<Params, Progress, Result>
public void onStart(){ … WorkAsyncTask wt = new WorkAsyncTask(); wt.execute(string1, string2, string3); } private class WorkAsyncTask extends AsyncTask<String,Long,Boolean>{ void onPreExecute() { // faire patienter l’utilisateur, affichage d’un sablier… Boolean doInBackGround(String... t){ // effectuer la tâche coûteuse en temps // t[0]/string1, t[1]/string2,… void onProgressUpdate(Long... v) { // informer l’utilisateur que le traitement est en cours void onPostExecute(Boolean b) { // le sablier disparaît, une éventuelle erreur est affichée
56
Chargement des items d’une liste et AsyncTask
Si le chargement des items d’une liste devient coûteux en temps d’exécution Alors ce chargement pourrait être effectué en tache de fond Construction de la liste item par item en tâche de fond Usage de AsyncTask Reprenons le premier exemple …
57
Une exemple d’usage d’AsyncTask
ConstructionListe extends AsyncTask ArrayAdapter contient une liste vide, Celle-ci sera affectée en tache de fond
58
ConstructionListe extends AsyncTask
Construction de la liste en tache de fond …
59
private class ChargeurDeLaListe
Le chargement de la liste nécessite une requête sur le web : encore AsyncTask private class ChargeurDeLaListe extends AsyncTask<URL, Void, Boolean>{ ProgressDialog dialog void onPreExecute() { dialog = ProgressDialog( // … Boolean doInBackGround(URL... t){ UneListe = Résultat d’une Requete en URL[0]… void onPostExecute(Boolean b) { Affecter UneListe selon la stratégie ou bien prévenir si échec dialog.dissmiss(); }
60
Chargement d’un item d’une liste et AsyncTask
Si le chargement d’un item d’une liste devient coûteux en temps d’exécution Usage de AsyncTask Source
61
Source http://lucasr.org/2012/04/05/performance-tips-for-androids-listview/
62
CursorAdapter et les contacts
Autre support …
63
Sauvegarde / restitution du modèle
Par exemple entre deux rotations de l’écran… Une solution Classe interne et statique + Variable de classe Soit : Une zone mémoire de la DVM, indépendante du cycle de vie de l’activité Nous préférerons un service très inspiré de
64
// restitution éventuelle
A la création public class ListeActivity extends ListActivity { private static Modèle modèle; public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); // restitution éventuelle modèle = (Modèle) getLastNonConfigurationInstance(); }
65
Démarrage et Sauvegarde au cas où
@Override public Object onRetainNonConfigurationInstance() { return modèle; } À lire :
66
Architecture logicielle
MVC Une proposition / discussion
67
Architecture MVC, rappel
Application: Une liste d’item : le modèle, du java standard, portable ListView + ListActivity : la Vue Un Receiver : le Contrôleur
68
Android Les outils nécessaires Intent IntentFilter BroadcastReceiver
registerReceiver
69
La vue, une liste d’items
Affichage Opérations d’ajout et de suppression
70
La liste d’items le modèle Items la vue le contrôleur MainActivity
extends Observable la vue le contrôleur MainActivity extends ListActivity implements Observer MainActivity extends ListActivity implements Observer ItemsControler extends BroadcastReceiver ItemsController extends BroadcastReceiver Items : le modèle MainActivity : la vue ItemsController : le contrôleur
71
La classe Items : le modèle
Java J2SE portable synchronized(this) par précaution (plusieurs contrôleurs)
72
Architecture suite Items : le modèle MainActivity : la vue
extends java.util.Observable MainActivity : la vue extends android.app.ListActivity implements java.util.Observer ItemsController : le contrôleur extends android.content.BraoadcastReceiver
73
Le contrôleur est un BroadcastReceiver
Items extends Observable MainActivity extends ListActivity implements Observer MainActivity extends ListActivity implements Observer ItemsController extends BroadcastReceiver ItemsControler extends BroadcastReceiver sendBroacast A chaque Click sendBroadcast Intent intent = new Intent(); intent.setAction(ItemsController.ACTION); … sendBroadcast(
74
Action de l’utilisateur, gérée par le contrôleur
MainActivity extends ListActivity implements Observer MainActivity extends ListActivity implements Observer ItemsController extends BroadcastReceiver ItemsControler extends BroadcastReceiver sendBroacast sendBroadcast
75
ItemsController A chaque « clic » la méthode onReceive est exécutée
abortBroadcast(); si non cumul du comportement
76
Contrôleur -> Modèle
Items extends Observable ItemsController extends BroadcastReceiver ItemsControler extends BroadcastReceiver Appel de la méthode ajouter du modèle
77
Modèle -> Vue Items MainActivity
extends Observable MainActivity extends ListActivity implements Observer La méthode update est déclenchée au sein de l’activité
78
La Vue 1/4 initialisation
onCreate de l’activité Création du modèle et du contrôleur
79
La Vue 2/4 enregistrement du contrôleur
onResume de l’activité (ou onCreate, dépend de l’application) enregistrement du contrôleur onPause (ou onDestroy)
80
La Vue 3/4 A chaque clic ! onClickAjouter
81
La Vue 4/4 update update appelée par le modèle (extends Observable)
La vue est un observateur( implements java.util.Observer)
82
Discussion
83
MVC Items MVC respecté Couplage faible conservé
extends Observable MVC respecté Couplage faible conservé Au sein de la même application MainActivity extends ListActivity implements Observer MainActivity extends ListActivity implements Observer ItemsController extends BroadcastReceiver ItemsController extends BroadcastReceiver AnotherActivity extends Activity implements Observer CloudController web, cloud
84
Généralisation Items MVC respecté Couplage faible conservé
extends Observable MVC respecté Couplage faible conservé MainActivity extends ListActivity implements Observer MainActivity extends ListActivity implements Observer ItemsController extends BroadcastReceiver AnotherActivity extends Activity implements Observer GenericController web, cloud Le champ Action sélectionne le contrôleur ad’hoc
85
GenericController ItemsController extends BroadcastReceiver GenericController L’ACTION_KEY est redirigée vers le « bon » contrôleur Discussion
86
Cumul du comportement ItemsController ItemsControllerPlus
extends BroadcastReceiver ItemsControllerPlus extends ItemsController Avec une sous classe de ItemsController: ItemsControllerPlus @Override onReceive(Context context, Intent intent){ super.onReceive(context, intent); …
87
Démonstration Discussion Architecture logicielle et Processus …
Présentations similaires
© 2024 SlidePlayer.fr Inc.
All rights reserved.