Je ne m'attarderai pas sur le web-service lui-même (qui sort du sujet de cette série de billet), et son implémentation (PHP, .Net, .cgi, Java...) est complètement indépendante de ce qui va suivre.
Nous partirons toutefois du principe que ce web-service (un service distant communiquant par http / https) va donner ses réponses dans un format "JSON" (à priori JSON "Object", puisque je le rappelle, l'utilisation des "array" JSON contient un certain risque de sécurité côté HTML).
Donc nous avons:
- Une application Android. Une activité de cette application nécessite d'afficher une liste de pays et la taille de leur population (ListView).
- Un webservice qui fournira cette liste de manière dynamique, sous une forme de JSON Object. Disons que ce service sera accessible à l'URL suivant: "http://un.example.com/population.php"
La première règle en développement est d'avoir une première implémentation visuelle rapidement. Il est souvent psychologiquement plus intéressant de rendre une interface dynamique, que de transformer une foultitude de données dynamique en une interface.
Commençons donc par la partie "interface":
Code java : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 | // le choix du nom est primordial pour savoir: ce que fait l'objet, mais aussi de quel type générique il est class ListePopulationActivity extends Activity { private ListView listeView; // on définit les données sur lesquelles on va travailler... à noter que cette classe pour être déclarée extérieurement à l'activité, cela ne changerait rien puisqu'elle est "statique". // on utilise aussi les vrais types de données, afin de bénéficier du fait que Java soit fortement typé. Ceci permettra de détecter les erreurs de base avant la compilation. public static class Pays { private String name; private long population; public Pays(String n, long v) { this.name = n; this.population = v; } public Pays() { } public void setName(String n) { this.name = n; } public void setPopulation(long v) { this.population = v; } public String getName() { return this.name; } public long getPopulation() { return this.population; } }; @Override public void onCreate(Bundle args) { // ces lignes devraient toujours être présente dès le début de la fonction. super.onCreate(args); setContentView(R.layout.activity_liste_population); // on suppose qu'un layout a été fait, et qu'il contient un objet de type ListView, ayant pour id "R.id.liste_population" this.listeView = (ListView) findViewById(R.id.liste_population); // a présent, on peut préparer les "listeners" pour réagir aux actions de l'utilisateur, comme onItemClicked() ou autres // on met à jour les données de la liste. populateListe(); } private void populateListe() { ArrayList<Pays> data = new ArrayList<Pays>(); //dans notre premier billet, nous allons populer la liste avec de "fausses" données (en anglais: "mock-data"). On en profitera pour tester le comportement de l'interface sur des données "limites". data.add(new Pays("Test 1",45789999)); data.add(new Pays("Test 2",0)); data.add(new Pays("Test 3",147)); data.add(new Pays("Test 4",999999999)); // nos données sont populées... il ne reste plus qu'à mettre à jour la liste updateList(data); } private void updateListe(List<Pays> data) { // nous allons définir PaysAdapter juste après PaysAdapter adapter = new PaysAdapter(this,data); this.listeView.setAdapter(adapter); } // contrairement aux données qui sont publiques et pourraient avoir leur propre fichier // notre adapter devrait lui rester privé à la classe. En effet il fait partie intégrante de la représentation (comme l'activité) private static class PaysAdapter extends ArrayAdapter<Pays> { private NumberFormat popFormat; public PaysAdapter(Context ctxt, List<Pays> data) { super(ctxt,R.layout.pays_item,R.id.texte,data); // le format des populations. Préférable à Long.toString() qui est purement "code", NumberFormat permet // de gérer correctement les ',' (ou '.') dépendants de la locale courante. this.popFormat = NumberFormat.getInstance(); } public View getView(int position, View convertView, ViewGroup parent) { // on laisse ArrayAdapter faire le boulot de création de la view View ret = super.getView(position,convertView,parent); // on va juste mettre ici les bonnes données au bon endroit Pays pays = getItem(position); TextView nameView = (TextView) ret.findViewById(R.id.name); nameView.setText(pays.getName()); TextView popView = (TextView) ret.findViewById(R.id.population); popView.setText(this.popFormat.format(pays.getPopulation())); return ret; } } |
Voilà... notre première partie est faite....
L'activité devrait s'afficher, avec les données de test, correctement.
Nous verrons dans la Partie 2 comment faire pour que ces données viennent... d'un webservice.
Pour information (et histoire que vous puissiez faire le test) voici les deux fichiers de layout:
activity_liste_population.xml
Code xml : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context="com.example.test.ListePopulationActivity" > <TextView android:id="@+id/textView1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/hello_world" /> <ListView android:id="@+id/liste_population" android:layout_width="match_parent" android:layout_height="0dp" android:layout_alignParentBottom="true" android:layout_alignParentLeft="true" android:layout_alignParentRight="true" android:layout_below="@+id/textView1" > </ListView> </RelativeLayout> |
Code xml : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | <?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="wrap_content" android:orientation="horizontal" > <TextView android:id="@+id/name" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="left" android:text="TextView" /> <TextView android:id="@+id/population" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="right" android:text="TextView" /> </LinearLayout> |