Vous êtes sur la page 1sur 78

Aller plus loin dans le dveloppement Android

Par AndroWiiid

www.siteduzero.com

Licence Creative Commons 6 2.0 Dernire mise jour le 4/01/2013

2/79

Sommaire
Sommaire ........................................................................................................................................... 2 Lire aussi ............................................................................................................................................ 1 Aller plus loin dans le dveloppement Android ................................................................................... 3
Bonjour amis Zros, .......................................................................................................................................................... 3

Partie 1 : Fragmenter vos projets ........................................................................................................ 4


Fragment ........................................................................................................................................................................... 4
Introduction aux fragments .......................................................................................................................................................................................... 4 Les fragments, kzako ? ............................................................................................................................................................................................. 4 Le cycle de vie des fragments ..................................................................................................................................................................................... 4 La bibliothque de compatibilit .................................................................................................................................................................................. 5 Utiliser des fragments fixes ......................................................................................................................................................................................... 6 Cration d'un fragment ................................................................................................................................................................................................ 6 Rarranger les fragments en paysage ........................................................................................................................................................................ 8 Utiliser des fragments dynamiques ........................................................................................................................................................................... 10 Grer ses fragments .................................................................................................................................................................................................. 10 Le contrleur des fragments ..................................................................................................................................................................................... 10 Retenir sa position dans les fragments ..................................................................................................................................................................... 13

ListFragment ................................................................................................................................................................... 16
Utilisation simple des listes ....................................................................................................................................................................................... Dclarer sa liste dans des fichiers XML .................................................................................................................................................................... Cration de la ListFragment ...................................................................................................................................................................................... Intgrer une vue personnalise ................................................................................................................................................................................. Crer une vue personnalise .................................................................................................................................................................................... Crer son adaptateur ................................................................................................................................................................................................ Vers des listes dynamiques ....................................................................................................................................................................................... Modification de l'adaptateur ...................................................................................................................................................................................... Paramtriser son application ..................................................................................................................................................................................... Dfinir ses prfrences ............................................................................................................................................................................................. Crer son fragment avec son activit ........................................................................................................................................................................ Affiner ses paramtres avec les en-ttes .................................................................................................................................................................. Dfinir les en-ttes .................................................................................................................................................................................................... Attacher une activit ............................................................................................................................................................................................... Lire les prfrences ................................................................................................................................................................................................... 16 16 17 18 18 20 22 22 28 28 30 31 32 33 34

PreferenceFragment ....................................................................................................................................................... 28

DialogFragment ............................................................................................................................................................... 36
Crer un DIalogFragment .......................................................................................................................................................................................... 36 Crer un AlertDialog .................................................................................................................................................................................................. 37 Afficher une boite de dialogue ................................................................................................................................................................................... 39 Correction .................................................................................................................................................................................................................. 40

Partie 2 : Des nouveaux composants ............................................................................................... 41


La barre d'action des applications ................................................................................................................................... 42
Intgrer un menu ....................................................................................................................................................................................................... 42 Possibilits avances ................................................................................................................................................................................................ 44 Barre de recherche .................................................................................................................................................................................................... 44 Partage travers le systme ..................................................................................................................................................................................... 46 Spliter le menu .................................................................................................................................................................................................... 48 Bouton home ............................................................................................................................................................................................................. 49 Menu contextuel ........................................................................................................................................................................................................ 50

Slider travers des crans ............................................................................................................................................. 52


Passer des informations la cration d'un fragment ................................................................................................................................................ Utilisation du widget ViewPager ................................................................................................................................................................................ L'adaptateur du ViewPager ....................................................................................................................................................................................... Activit du ViewPager ............................................................................................................................................................................................... Ajout d'un indicateur de la page ................................................................................................................................................................................ Navigation en tab ...................................................................................................................................................................................................... Modifier l'indicateur ................................................................................................................................................................................................... Modifier la page ......................................................................................................................................................................................................... 53 54 54 55 56 57 57 58

Notifier l'utilisateur ........................................................................................................................................................... 62


Basique ..................................................................................................................................................................................................................... 62 Les diffrents styles ................................................................................................................................................................................................... 63 Grand texte ................................................................................................................................................................................................................ 64 Grande image ............................................................................................................................................................................................................ 65 Liste de chanes de caractres ................................................................................................................................................................................. 67 Ajouter des boutons d'action ..................................................................................................................................................................................... 69

Le partage par NFC ......................................................................................................................................................... 70


Les diffrents tags existants ...................................................................................................................................................................................... Identification des diffrents tags ................................................................................................................................................................................ Structure d'un message NDEF .................................................................................................................................................................................. Implmentation dans notre application ..................................................................................................................................................................... Lecture d'un tag ......................................................................................................................................................................................................... Activit destin grer la lecture du tag ................................................................................................................................................................... Un mulateur de tag NDEF ....................................................................................................................................................................................... Echange par Beam ................................................................................................................................................................................................... 71 71 71 72 72 72 74 76

www.siteduzero.com

Sommaire

3/79

Aller plus loin dans le dveloppement Android


Le tutoriel que vous tes en train de lire est en bta-test. Son auteur souhaite que vous lui fassiez part de vos commentaires pour l'aider l'amliorer avant sa publication officielle. Notez que le contenu n'a pas t valid par l'quipe ditoriale du Site du Zro.

Par

AndroWiiid

Mise jour : 04/01/2013 Difficult : Difficile 245 visites depuis 7 jours, class 323/798

Bonjour amis Zros,


Si crer des applications Android est devenue une passion pour vous grce l'excellent tutoriel de Apollidore qui aborde les bases du dveloppement Android, vous tes au bon endroit. La valeur ajoute de ce tutoriel est de vous permettre d'apprendre des notions sont parfois difficiles acqurir tant les ouvrages sont peu nombreux sur les nouvelles technologies intgres au systme. L'objectif de ce tutoriel est d'aborder des notions avances sur le dveloppement Android en restant accessible pour les dbutants. Tout ce qui figurera sera consciencieusement expliqu afin de vous permettre d'en comprendre les concepts et de pouvoir les mettre en pratique directement, travers des travaux pratiques srieux. Pour parvenir atteindre cet objectif, nous aborderons : L'utilisation de fragments pour confectionner des interfaces souples et avances. Les derniers composants ajoutes dans les dernires versions d'Android. La mise en place d'un serveur pour nous permettre d'alimenter nos applications par aprs. La gestion de donnes partages avec, entre autre, la rcupration des donnes sur une base de donnes distantes. L'intgration d'une Google Map de la gnration de la cl API aux marqueurs placer sur la map. L'utilisation de librairies communautaires pour vous aider dans le dveloppement Android. Si ce menu vous parait intressant suivre, attendez de lire le tutoriel et d'en apprendre plus. V ous pouvez retrouver tous les codes sources de ce tutoriel sur ce projet GitHub.

www.siteduzero.com

Aller plus loin dans le dveloppement Android

4/79

Partie 1 : Fragmenter vos projets


Depuis Android 3, une nouvelle notion est apparue dans le dveloppement d'application, Fragment. Les fragments sont maintenant utiliss pour le dveloppement de toutes les applications (du moins srieuses) sur le Play Store. Cela nous permettra d'isoler des portions d'interface que nous allons grer dans des classes fragments plutt que dans une Activity. Nous verrons aussi qu'ils ressemblent beaucoup aux activits, que cela soit dans son cycle de vie ou dans les diffrentes types de classe qu'il peut crer. Ainsi, nous aurons le type de base, les listes, les boites de dialogue et ceux conus pour paramtriser ses applications. Nous verrons l'utilisation de chacun d'eux via des exemples simples mais prcis pour expliquez comment ces classes fonctionnent.

Fragment
Introduction aux fragments Les fragments, kzako ?
La notion de fragment est souvent confuse pour les dbutants et pas toujours bien comprise par ceux qui commencent programmer assez rgulirement sur la plateforme Android. Les fragments sont mi-chemin entre l'activit et la vue ; c'est--dire qu'il ne s'agit ni de l'un, ni de l'autre mais qu'ils sont troitement lis. V otre fragment consiste dfinir un morceau d'interface que vous pourrez attacher plusieurs endroits, sur des activits. Par exemple, dans le cas o vous dsirez rendre compatible votre application sur smartphone et sur tablette, vous n'aurez pas spcialement envie avoir la mme interface. La taille d'cran des tablettes tant largement plus grande que celles des smartphones, il serait dommage de ne pas en profiter. L'ide consiste de dfinir des fragments que vous afficherez un un sur un smartphone et plusieurs sur tablette. Si vous avez une liste de news (par hasard ? ). Sur votre smartphone, vous afficherez cette liste et une fois que l'utilisateur aura effectu une pression sur l'un des items de la liste, vous lancerez un autre cran avec les dtails de la news slectionne. Quant la version tablette, vous afficherez la liste des news gauche et directement droite les dtails de la news slectionne, sans changer d'cran. Ce genre de chose est possible grce aux fragments !

Le cycle de vie des fragments


V ous connaissez certainement les activits (j'espre en tout cas sinon il y a du souci se faire ) et leurs cycles de vie. Celui des fragments est trs similaire et en mme temps troitement li avec l'activit laquelle est attach. V ous retrouvez toutes les mthodes callback d'une activit, savoir onCreate, onStart, onResume, onPause, onStop et onDestroy. Ces mthodes ont exactement le mme but dans les fragments que dans les activits. Cependant, il en rajoute quand mme qui sont appels par l'activit hte du fragment. Nous verrons l'utilit de ces nouvelles mthodes dans la suite de ce chapitre. V ous pouvez voir l'ensemble des mthodes via le schma ci-dessous disponible sur le portail des dveloppeurs Android .

www.siteduzero.com

Partie 1 : Fragmenter vos projets

5/79

Cycle de vie des fragments disponible partir du site des

dveloppeurs Android

La bibliothque de compatibilit
C'est bien beau n'est-ce pas ? Un monde o vous pouvez librement placer des fragments aux endroits que vous dsirez pour optimiser vos applications sur le plus d'appareil possible. Malheureusement, ce n'est pas si simple. Au dbut, Android tait ddi uniquement aux smartphones ; c'est--dire des crans de moins de 4 pouces (les smartphones de plus de 4 pouces ne sont

www.siteduzero.com

Partie 1 : Fragmenter vos projets

6/79

arrivs que trs rcemment l'heure o j'cris ces lignes). Par aprs, Google a tendu son systme aux tablettes avec la version 3 (les versions 2 et moins taient donc destins aux smartphones) et la version 4 qui unifie les 2 types. Aujourd'hui, on commence de plus en plus voir des TV avec Android comme systme. Il est tout fait possible de dvelopper pour ce genre d'appareil mais les bonnes pratiques d'ergonomie sont encore un peu vague. C'est pourquoi nous ne verrons pas d'exemple concret pour les TV mais les techniques que vous apprendrez dans ce tutoriel vous permettront d'en dvelopper. C'est avec cette version 3, HoneyComb, qu'est apparu les fragments. Techniquement, ce composant (et les autres que nous verrons dans la suite de cette premire partie) n'est pas disponible en dessous de cette version. Comment pouvons-nous donc dvelopper notre application sans devoir crer deux projets (un pour les versions 2 et antrieur et un autre pour la version 3 et suprieur) ? Je vous ai dj dit que Google tait une boite formidable ? Maintenant, je vous le dis. Google est une boite formidable ! Ils ont dvelopp une librairie de compatibilit qui vous permettra d'utiliser une trs grande partie des fonctionnalits disponibles partir de la version 3 d'Android ds la version 2.1. Soit regrouper environ 95% du march des appareils tournant avec Android. Nous apprendrons l'utiliser et aller plus loin grce un projet communautaire de compatibilit que nous verrons plus loin dans ce tutoriel.

Utiliser des fragments fixes


V ous savez maintenant ce que sont des fragments. V ous n'avez peut-tre pas saisi compltement son utilit mais vous comprendrez vite. Il existe deux manires d'intgrer des fragments dans une activit : de manire fixe en spcifiant vos fragments directement dans un fichier XML d'affichage ou dynamiquement avec l'aide d'outils mis disposition aux dveloppeurs par Android. Nous aborderons d'abord le plus simple, les fragments fixes, et dans la suite de ce chapitre, la manire dynamique.

Cration d'un fragment


Avant de pouvoir utiliser des fragments, il va falloir savoir comment nous pouvons en crer. Pour ce faire, c'est trs simple. Avec un peu de rflexion, vous pourriez parvenir le faire vous mme parce que c'est quasiment identique aux activits. Il vous suffit de dfinir une portion d'interface dans un fichier XML d'affichage et de l'attacher un Fragment, quelques diffrences prs. A savoir que nous ne dsrialisons pas notre fichier XML dans la mthode public void onCreate (Bundle savedInstanceState) mais partir de la mthode public View onCreateView (LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) dont le premier paramtre vous permettra de le faire. De plus, et chose importante, Eclipse vous proposera d'importer deux paquetages pour avoir accs Fragment (android.app.Fragment et android.support.v4.app.Fragment). Quel est la diffrence entre ces 2 fragments ? Le premier redirige vers le Fragment de la version d'Android que vous avez dlimit dans le manifest de votre projet ; c'est-dire que vous n'aurez pas accs cet import si vous n'tes pas une version 3 et plus puisque Android 2 ne connait normalement pas les fragments. Le deuxime redirige vers le Fragment du projet de compatibilit Google (bibliothque inclut automatiquement lors de la cration d'un nouveau projet dans les rcents ADT). Sauf si vous ne dsirez pas rendre vos futurs programmes compatibles avec les anciens terminaux, nous utiliserons chaque fois les imports de la bibliothque de compatibilit. Il faudra constamment faire attention aux imports dans vos projets. C'est une erreur commune chez les dveloppeurs dbutants mais aussi expriments. Google a tent de rendre l'utilisation de la bibliothque le plus proche de son utilisation normal. Mise part quelques mthodes, elles auront globalement les mmes signatures. Pour notre exemple, nous allons faire quelque chose de simple. Nous allons simplement placer un TextView au centre du fichier XML d'affichage que nous attacherons un Fragment qui sera lui mme attach une Activity. Nous allons nommer notre fichier XML d'affichage fragment_fixe et nous placerons dedans : Code : XML <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerHorizontal="true"

www.siteduzero.com

Partie 1 : Fragmenter vos projets


android:layout_centerVertical="true" android:text="@string/title_fragment_fixe" /> </RelativeLayout>

7/79

Nous dsrialisons ce fichier XML d'affichage dans un fragment que nous nommerons FixeFragment : Code : Java package com.siteduzero.android.fragments.fixe; import import import import import android.os.Bundle; android.support.v4.app.Fragment; android.view.LayoutInflater; android.view.View; android.view.ViewGroup;

import com.siteduzero.android.R; public class FixeFragment extends Fragment { @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { return inflater.inflate(R.layout.fragment_fixe, container, false); } }

V ous remarquerez que je spcifie exprs la dfinition du paquetage et les imports. C'est une chose importante dans les fragments, cela sera une habitude prise dans ce tutoriel pour que vous ne soyez jamais perdu. V ous pouvez vous rendre compte de la simplicit dconcertante de la cration d'un fragment. Son utilisation est tout aussi simple lorsque vous l'attachez fixement une activit. Dans chaque activit, nous allons crer un autre fichier XML d'affichage, que nous nommerons activity_fragment_fixe, et dans lequel nous allons dclarer un widget Fragment qui spcifie dans son attribut android:name notre FixeFragment. Code : XML <?xml version="1.0" encoding="utf-8"?> <fragment xmlns:android="http://schemas.android.com/apk/res/android" android:name="com.siteduzero.android.fragments.fixe.FixeFragment" android:layout_width="match_parent" android:layout_height="match_parent" />

Dans le code de l'activit, FixeActivity , il nous suffit simplement de dsrialiser le fichier XML d'affichage que nous venons de crer pour attacher notre Fragment et d'tendre la classe FragmentActivity la place de Activity pour notifier Android que nous utilisons des Fragment. Code : Java package com.siteduzero.android.fragments.fixe; import com.siteduzero.android.R; import android.os.Bundle; import android.support.v4.app.FragmentActivity; public class FixeActivity extends FragmentActivity { @Override protected void onCreate(Bundle arg0) { super.onCreate(arg0); setContentView(R.layout.activity_fragment_fixe);

www.siteduzero.com

Partie 1 : Fragmenter vos projets


} }

8/79

Qu'est ce que nous pouvons en dire ? V ous pouvez vous rendre compte que l'activit est vide, peu importe ce que vous placez dans un fragment. C'est l'une des forces de l'utilisation des fragments. Habituellement, les activits jouent le rle des contrleurs dans une architecture MVC (patron architectural sur lequel Android se base dans le dveloppement d'application). Dans notre cas, les fragments joueront le rle de contrleurs pour les vues qu'ils instancient. Cela permet de maintenir plus aisment le code et de sparer les responsabilits entre diffrentes classes.

Rsultat de l'excution de l'activit

FixeActivity

www.siteduzero.com

Partie 1 : Fragmenter vos projets

9/79

Rarranger les fragments en paysage


Cependant, ce n'est pas parce que nous dfinissons des diagrammes fixes que nous ne pouvons pas faire des choses intressantes. C'est pourquoi je vais vous expliquer comment rarranger vos fragments lorsque vous basculez votre appareil en mode paysage. L'ide est la suivante. Nous voulons afficher FixeFragment lorsque nous sommes en mode portrait et deux fois l'un ct de l'autre en mode paysage. V ous tes cens avoir une petite ide de la marche suivre si vous avez dj dvelopp sur Android ou si vous avez suivi le tutoriel officiel d'Android pour dbutant du Site du Zro. C'est pourquoi je vais vous laisser rflchir sur le problme pour parvenir ce rsultat :

Rsultat de l'excution de l'activit FixeActivity en paysage

Correction
V ous avez russi trouver quelque chose ? Si vous tes parvenu un rsultat similaire au mien, c'est dj pas mal. Si vous avez la mme solution que moi, c'est encore mieux. Pourquoi ? Simplement parce que la solution la plus simple pour parvenir mon rsultat est de crer un nouveau fichier XML d'affichage du mme nom que celui de l'activit qui se trouve dans le dossier layout mais dans le layout-land et en dfinissant les deux Fragment dans ce fichier. Le systme se rendra automatiquement dans ce dossier pour rcuprer le bon fichier XML et tout sera fait automatiquement ! Code : XML <?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="match_parent" android:orientation="horizontal" > <fragment android:name="com.siteduzero.android.fragments.fixe.FixeFragment" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_weight="1" /> <fragment android:name="com.siteduzero.android.fragments.fixe.FixeFragment"

www.siteduzero.com

Partie 1 : Fragmenter vos projets


android:layout_width="match_parent" android:layout_height="match_parent" android:layout_weight="1" /> </LinearLayout>

10/79

Utiliser des fragments dynamiques


On va faire quelque chose d'encore plus intressant. Habituellement, lorsque vous dveloppez vos applications, vous dfinissez des crans fixes. J'entends par l que rien ne change pendant son excution. Cliquez sur un bouton ouvre une nouvelle activit qui affiche les widgets dclars dans son fichier XML d'affichage. Il est bien possible de masquer des portions d'interface mais ce n'est jamais trs performant (voire joli). Les fragments apportent une solution simple et performant pour modifier dynamiquement l'interface de nos crans.

Grer ses fragments


Android met disposition des dveloppeurs une interface indispensable pour grer ses fragments dynamiquement, FragmentManager. Cette interface offre plusieurs services dont un qui nous intresse tout particulirement : grer des transactions. Comment a fonctionne ? Chaque opration sur les fragments doivent tre regroupe dans une transaction accessible partir du FragmentManager. Utiliser ces services est trs simple mais il ne faut pas oublier que nous utilisons la bibliothque de compatibilit de Google. L'initialisation du manager est donc un peu diffrente. V ous aurez sans doute remarqu le mot cl "support" dans l'importation de la classe Fragment. Ce mot cl n'est pas un hasard et se retrouvera un peu partout dans l'utilisation des classes venant de la bibliothque. Ainsi, pour initialiser, vous utiliserez non pas la mthode public FragmentManager getFragmentManager() mais la mthode public FragmentManager getSupportFragmentManager(). Si vous utilisez des fragments qui viennent du paquetage android.app.Fragment mais que vous utilisez FragmentManager de la bibliothque de compatibilit (ou inversement), vous aurez une erreur. V ous tes oblig de faire un choix !

Le contrleur des fragments


V ous vous souvenez ce que je vous ai dit au sous-chapitre prcdent ? Les activits ne servent plus de contrleurs des vues qu'elles contiennent. Cependant, elles deviennent contrleurs des fragments qu'elles contiennent, encore plus lorsqu'elles doivent les grer dynamiquement. C'est la responsabilit de l'activit de grer l'affichage du fragment qu'on dsire. Qu'allonsnous faire ? Nous allons crer deux fragments qui afficheront, pour les deux, un TextView et un Button. Cela nous permettra de switcher d'un fragment l'autre en appuyant sur le bouton. Je pars du principe que la cration d'un fragment est quelque chose d'acquis maintenant. Je vous laisse votre bon soin de crer les fragments Dynamic1Fragment et Dynamic2Fragment. Le rel changement sera dans notre activit, DynamicActivity. Premire chose, son fichier XML d'affichage ne comportera aucun fragment mais un FrameLayout. Il servira de conteneur pour nos fragments. V ous comprendrez bien assez vite. Sachez simplement que vous devrez lui donner un identifiant afin de pouvoir remplacer son contenu par un autre. Seconde chose, nous allons devoir structurer notre code. A partir de la mthode public void onCreate(Bundle savedInstanceState), nous appelerons deux mthodes : private void setupFragments() et private void showFragment(final Fragment fragment). La premire mthode initialisera les diffrents fragments et ne sera appel qu' partir de la mthode onCreate. La seconde mthode se chargera d'afficher le fragment qu'on passe en paramtre l'cran. Elle pourra tre appel partir des boutons.

Initialisation des fragments


Si je vous demandais d'initialiser les fragments, je sais ce que vous feriez. Sans doute quelque chose qui ressemble this.mDynamic1Fragment = new Dynamic1Fragment();. V ous n'avez pas tout fait tord mais il ne faut jamais perdre l'esprit que nous dveloppons sur des appareils mobiles et il n'y a pas de petites conomies. Si Android parvient sauvegarder en cache nos fragments, cela serait bien de pouvoir les rcuprer. Il existe deux manires d'y parvenir, par identifiant ou par tag. Comme nous avons des classes fragments, le plus simple est d'utiliser les tags. Il suffit de rajouter une constante publique dans nos fragments pour leur donn un nom unique. Pour utiliser ces tags, nous rcuprerons le FragmentManager pour appeler dessus la mthode public abstract Fragment findFragmentByTag (String tag). Avant d'initialiser nos fragments, nous essayerons de les rcuprer par le biais de cette mthode afin d'conomiser de la mmoire ! V oici quoi ressemble notre mthode avec nos deux fragments :

www.siteduzero.com

Partie 1 : Fragmenter vos projets


Code : Java private void setupFragments() { final FragmentManager fm = getSupportFragmentManager(); this.mDynamic1Fragment = (Dynamic1Fragment) fm .findFragmentByTag(Dynamic1Fragment.TAG); if (this.mDynamic1Fragment == null) { this.mDynamic1Fragment = new Dynamic1Fragment(); } this.mDynamic2Fragment = (Dynamic2Fragment) fm .findFragmentByTag(Dynamic2Fragment.TAG); if (this.mDynamic2Fragment == null) { this.mDynamic2Fragment = new Dynamic2Fragment(); }

11/79

Remplacer les fragments


La seconde mthode consistera simplement afficher le fragment pass en paramtre sur l'cran en remplaant le contenu du FrameLayout. Pour ce faire, nous avons besoin d'une transaction sur laquelle nous allons devoir appeler la mthode public abstract FragmentTransaction replace (int containerViewId, Fragment fragment). Son utilisation est simple, donner l'identifiant du layout conteneur et le fragment remplacer. On implmentera la mthode de la manire suivante : Code : Java private void showFragment(final Fragment fragment) { if (fragment == null) return; final FragmentManager fm = getSupportFragmentManager(); final FragmentTransaction ft = fm.beginTransaction(); // We can also animate the changing of fragment ft.setCustomAnimations(android.R.anim.slide_in_left, android.R.anim.slide_out_right); ft.replace(R.id.frameLayoutListView, fragment); } ft.commit();

Chaque transaction doit appeler la mthode commit() pour voir ses oprations s'effectuer. En cas contraire, aucune erreur ne sera lance mais rien ne se passera.

Rsultat final
Mais attends une seconde. C'est bien beau tout a mais je fais comment pour appeler la mthode private void showFragment(final Fragment fragment) lorsque je clique sur mes boutons ? Mes fragments ne connaissent pas forcment l'activit prcise dans lequel il se trouve. V ous n'avez pas tord mais Google a apport une rponse ce lger problme. L'un des attributs que vous pouvez donner vos boutons est le suivant : android:onClick. La valeur que vous donnez cet attribut vous oblige implmenter une mthode du mme nom dans l'activit dans laquelle il est dsrialis. Du coup, dans le fichier XML d'affichage de fragment 1 et 2, nous avons donn les valeurs respective goToFragment2 et goToFragment1. Par consquent, nous implmentons notre activit de la manire suivante : Code : Java public class DynamicActivity extends FragmentActivity {

www.siteduzero.com

Partie 1 : Fragmenter vos projets


private String mFragment; private Dynamic1Fragment mDynamic1Fragment; private Dynamic2Fragment mDynamic2Fragment; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_fragment_dynamic); mFragment = getIntent().getStringExtra("fragment"); setupFragments(); if (mFragment.equals("Dynamic1Fragment")) { showFragment(this.mDynamic1Fragment); } else if (mFragment.equals("Dynamic2Fragment")) { showFragment(this.mDynamic2Fragment); }

12/79

private void setupFragments() { final FragmentManager fm = getSupportFragmentManager(); this.mDynamic1Fragment = (Dynamic1Fragment) fm .findFragmentByTag(Dynamic1Fragment.TAG); if (this.mDynamic1Fragment == null) { this.mDynamic1Fragment = new Dynamic1Fragment(); } this.mDynamic2Fragment = (Dynamic2Fragment) fm .findFragmentByTag(Dynamic2Fragment.TAG); if (this.mDynamic2Fragment == null) { this.mDynamic2Fragment = new Dynamic2Fragment(); }

private void showFragment(final Fragment fragment) { if (fragment == null) return; final FragmentManager fm = getSupportFragmentManager(); final FragmentTransaction ft = fm.beginTransaction(); // We can also animate the changing of fragment ft.setCustomAnimations(android.R.anim.slide_in_left, android.R.anim.slide_out_right); ft.replace(R.id.frameLayoutListView, fragment); } ft.commit();

public void goToFragment1(View v) { showFragment(this.mDynamic1Fragment); } public void goToFragment2(View v) { showFragment(this.mDynamic2Fragment); }

Si vous excutez notre application, lorsque vous cliquez sur l'un des boutons des fragments, le fragment courant s'animera en se dplaant vers la droite pour laisser place notre second fragment. V ous constatez qu'en plus de pouvoir facilement de fragment, il est simple d'effectuer quelques animations sur le changement.

www.siteduzero.com

Partie 1 : Fragmenter vos projets

13/79

Rsultat de l'excution de l'activit

DynamicActivity

Retenir sa position dans les fragments


Tiens, je ne sais pas si vous l'avez remarqu mais, par exemple, si vous changez l'orientation de votre smartphone, vous retournez au point initial. N'y aurait-il pas moyen de sauvegarder cette information ? V ous tes cens savoir comment faire ce genre de chose, c'est pourquoi je vais vous laisser rflchir sur la question. V ous trouverez ma correction juste aprs.

Correction
Code : Java

www.siteduzero.com

Partie 1 : Fragmenter vos projets


package com.siteduzero.android.fragments.dynamic; import import import import import import android.os.Bundle; android.support.v4.app.Fragment; android.support.v4.app.FragmentActivity; android.support.v4.app.FragmentManager; android.support.v4.app.FragmentTransaction; android.view.View;

14/79

import com.siteduzero.android.R; public class DynamicActivity extends FragmentActivity { private String mFragment; private Dynamic1Fragment mDynamic1Fragment; private Dynamic2Fragment mDynamic2Fragment; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_fragment_dynamic); if (savedInstanceState != null) mFragment = savedInstanceState.getString("fragment"); else mFragment = getIntent().getStringExtra("fragment"); setupFragments(); if (mFragment != null) { if (mFragment.equals("Dynamic1Fragment")) { showFragment(this.mDynamic1Fragment); } else if (mFragment.equals("Dynamic2Fragment")) { showFragment(this.mDynamic2Fragment); } }

@Override protected void onSaveInstanceState(Bundle outState) { outState.putString("fragment", mFragment != null ? mFragment : ""); super.onSaveInstanceState(outState); } private void setupFragments() { final FragmentManager fm = getSupportFragmentManager(); this.mDynamic1Fragment = (Dynamic1Fragment) fm .findFragmentByTag(Dynamic1Fragment.TAG); if (this.mDynamic1Fragment == null) { this.mDynamic1Fragment = new Dynamic1Fragment(); } this.mDynamic2Fragment = (Dynamic2Fragment) fm .findFragmentByTag(Dynamic2Fragment.TAG); if (this.mDynamic2Fragment == null) { this.mDynamic2Fragment = new Dynamic2Fragment(); }

private void showFragment(final Fragment fragment) { if (fragment == null) return; final FragmentManager fm = getSupportFragmentManager(); final FragmentTransaction ft = fm.beginTransaction(); // We can also animate the changing of fragment ft.setCustomAnimations(android.R.anim.slide_in_left, android.R.anim.slide_out_right);

www.siteduzero.com

Partie 1 : Fragmenter vos projets


ft.replace(R.id.frameLayoutListView, fragment); } ft.commit();

15/79

public void goToFragment1(View v) { showFragment(this.mDynamic1Fragment); } public void goToFragment2(View v) { showFragment(this.mDynamic2Fragment); }

www.siteduzero.com

Partie 1 : Fragmenter vos projets

16/79

ListFragment
Le widget ListView est sans aucun doute l'un des composants graphiques les plus utiliss dans les applications Android, au mme titre que le ViewPager ou le GridView. Il permet d'afficher facilement des informations l'un la suite de l'autre verticalement avec des vues personnalises ou non. Dans un premier temps, nous allons voir comment utiliser ce composant ml la puissance des fragments. Nous compliquerons rapidement les choses en intgrant des vues personnalises chaque item de nos listes. Pour finir, nous rendrons l'affichage de cette liste dynamique avec l'apparition de vues diffrentes.

Utilisation simple des listes


Puisque les listes sont largement utilises dans les applications Android, nous allons partir du principe que les listes avec les Activity n'ont pas de secret pour vous. V ous tes cens savoir que vous pouvez en dfinir directement dans vos fichiers XML d'affichage ou via la classe ListActivity. Cependant, nous reviendrons plus en dtail sur les adaptateurs que vous devez crer lorsque vous en crez un vous mme. Il existe une manire simple et efficace de grer le cycle de vie des vues qu'ils grent mais trop peu connue de certains dveloppeurs. Bien entendu, l'adaptation aux fragments sera un point important de ce chapitre et l'utilisation, parfois mconnue, de certaines choses pour rendre vos applications plus agrable.

Dclarer sa liste dans des fichiers XML


Nous sommes partis du principe que vous saviez comment dclarer une liste partir d'un fichier XML d'affichage. Ce que vous ne savez peut-tre pas, c'est qu'il est possible de dfinir un fichier XML d'affichage avec des ListFragment. Si nous nous penchons sur le problme 30 secondes, cela pourrait vous semblez curieux. Pourquoi attacher un fichier XML une classe qui va crer automatiquement notre liste ? C'est trs simple. Par exemple, pour lui demander d'afficher quelque chose lorsque nous n'avons rien dans la liste. Ce que nous allons faire consiste dclarer une liste lorsqu'il y aura des lments afficher ou du texte pour indiquer l'utilisateur que la liste est vide. Pour nous permettre d'arriver ce rsultat, nous allons nous servir des id que le framework Android met disposition des dveloppeurs. En effet, il existe deux identifiants un peu spciaux contenu dans @android:id. Il donne accs soit list soit empty. Il permettra d'indiquer Android le composant afficher lorsqu'il y a une raison d'afficher une liste ou lorsqu'il n'y a rien dedans. Dans notre exemple, nous avons choisi d'afficher que du texte mais cela peut tre infiniment plus complet. V ous pourriez vouloir afficher une image et du texte en dessous. Dans ce cas l, il vous faudra mettre votre image et votre texte dans un layout que vous identifierez par la valeur empty. Si nous restons simple, le fichier XML ressemblera quelque chose comme ceci : Code : XML <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" > <ListView android:id="@android:id/list" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_alignParentTop="true" /> <TextView android:id="@android:id/empty" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerHorizontal="true" android:layout_centerVertical="true" android:text="@string/text_empty" /> </RelativeLayout>

www.siteduzero.com

Partie 1 : Fragmenter vos projets

17/79

Cration de la ListFragment
A la diffrence du chapitre prcdent, notre fragment ne va pas tendre la classe Fragment mais ListFragment qui est le parfait quivalent de la classe ListActivity. De la mme manire que les fragments basiques, nous allons dsrialiser notre fichier XML d'affichage dans sa mthode public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) (chose qui n'est pas obligatoire. V ous pouvez ne pas vouloir afficher quelque chose lorsque la liste est vide. Dans ce cas, il vous suffit de ne crer aucun fichier XML et de ne pas redfinir la mthode prcdemment cite). De la mme manire qu'une ListActivity, nous devons rcuprer notre liste pour lui attacher un adaptateur (que nous ne crerons pas pour le moment). L'unique subtilit dans ce cas prsent est la mthode redfinir. En effet, nous aurons accs notre liste qu'une fois l'activit dans laquelle le fragment est hberg sera construite. Nous faisons toutes les manipulations destines la gestion de la liste dans la mthode public void onActivityCreated(Bundle savedInstanceState). Ce qui nous donne le code et le rsultat suivant : Code : Java package com.siteduzero.android.lists; import com.siteduzero.android.R; import import import import import import android.os.Bundle; android.support.v4.app.ListFragment; android.view.LayoutInflater; android.view.View; android.view.ViewGroup; android.widget.ArrayAdapter;

public class SimpleListViewFragment extends ListFragment { public static final String TAG = "ListViewFragment"; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { return inflater.inflate(R.layout.fragment_listview, container, false); } @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); String[] items = getResources().getStringArray(R.array.list_examples); ArrayAdapter<String> aa = new ArrayAdapter<String>(getActivity(), android.R.layout.simple_list_item_1, items); setListAdapter(aa);

www.siteduzero.com

Partie 1 : Fragmenter vos projets

18/79

Rsultat de l'excution d'une liste simple

Intgrer une vue personnalise


Une liste remplie de texte est plutt rare dans les applications Android. En gnral, chaque item est une vue que vous avez vous mme confectionne pour afficher de l'information. Nous partons toujours du principe que vous savez faire ce genre de chose mais cela sera un peu diffrent cette fois. Je vais vous expliquer ma faon de faire pour que vous puissiez mettre en place une jolie architecture la fois souple et puissante.

Crer une vue personnalise


J'ose quand mme esprer que vous savez comment vous y prendre pour crer une vue (sinon, je vous redirige vers le tutoriel de Apollidore !). Pour notre exemple, nous allons faire quelque chose de trs simple : un petit bloc avec un ombrage qui contient du texte. Je vous rassure, vous n'allez pas devoir jouer avec 9-patch. Android vous fournit dj quelques ombrages que vous

www.siteduzero.com

Partie 1 : Fragmenter vos projets


pouvez utiliser comme bon vous semble. Notre fichier XML destin devenir notre vue ressemblera donc quelque chose comme ceci : Code : XML <?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:background="@android:drawable/dialog_holo_light_frame" android:orientation="vertical" > <TextView android:id="@+id/textView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:padding="15dp" android:text="@string/default_lorem" /> </LinearLayout>

19/79

Pour rester simple, notre classe Java, qui va dsrialiser notre fichier XML d'affichage, redfiniera simplement les constructeurs ncessaires pour appeler la super classe (LinearLayout) et offrira une mthode notre adaptateur pour attacher du texte notre TextView. Ainsi, nous obtenons le code suivant : Code : Java package com.siteduzero.android.lists; import com.siteduzero.android.R; import import import import android.content.Context; android.util.AttributeSet; android.widget.LinearLayout; android.widget.TextView;

public class CustomListViewView extends LinearLayout { private TextView mTextView; public CustomListViewView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); init(); } public CustomListViewView(Context context, AttributeSet attrs) { super(context, attrs); init(); } public CustomListViewView(Context context) { super(context); init(); } private void init() { inflate(getContext(), R.layout.view_custom_listview, this); mTextView = (TextView) findViewById(R.id.textView); } public void bind(int text) {

www.siteduzero.com

Partie 1 : Fragmenter vos projets


} mTextView.setText(getResources().getString(text));

20/79

Crer son adaptateur


Maintenant que nous avons une vue personnalise, la cration d'un adaptateur prend tout son sens. Mais nous allons faire a proprement. Il hritera de la classe BaseAdapter et offrira une mthode pour attacher les textes nos vues (vous l'aurez compris, c'est notre fragment qui se chargera de fournir tous les textes qui s'afficheront sur nos vues). Nous retiendrons donc une liste qui sera utilis par les mthodes que nous avons t forc de redfinir. Jusque l, rien de bien nouveau. Cependant, en plus de a, notre mthode public View getView(int position, View convertView, ViewGroup parent) ne se contentera pas de construire les vues. Il rcuprera au plus possible les vues dj construites et attachera le texte correspondant la ligne en cours le bon texte prsent dans notre liste. V ous devriez tre capable de concevoir cet adaptateur seul. C'est pourquoi je vous laisse y rflchir (et je vous conseil de le faire pour bien progresser). Aprs quoi, je vous invite consulter ma solution (que vous retrouverez cacher ci-dessous) pour vous corrigez. Secret (cliquez pour afficher) Code : Java package com.siteduzero.android.lists; import java.util.ArrayList; import java.util.List; import import import import android.content.Context; android.view.View; android.view.ViewGroup; android.widget.BaseAdapter;

public class CustomListViewAdapter extends BaseAdapter { private List<Integer> mModel = new ArrayList<Integer>(); private Context mContext; public CustomListViewAdapter(Context context) { mContext = context; } @Override public int getCount() { return mModel.size(); } @Override public Integer getItem(int position) { return mModel.get(position); } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { CustomListViewView v = null; // Notre vue n'a pas encore t construite, nous le faisons if (convertView == null) { v = new CustomListViewView(mContext); } // Notre vue peut tre rcupre, nous le faisons else {

www.siteduzero.com

Partie 1 : Fragmenter vos projets


v = (CustomListViewView) convertView; } v.bind(getItem(position)); return v;

21/79

public void bind(List<Integer> model) { mModel = model; }

Notre fragment sera exactement identique au prcdent sous-chapitre l'exception prs que nous n'utilisons plus ArrayAdapter mais notre propre adaptateur (CustomListViewAdapter dans mon cas). V ous devriez alors avoir le mme rsultat que moi avec une belle fluidit puisque notre adaptateur est optimis au niveau de la gestion de la mmoire.

www.siteduzero.com

Partie 1 : Fragmenter vos projets

22/79

Rsultat de l'excution d'une liste avec

une vue personnalise

Vers des listes dynamiques


Maintenant que nous avons appris l'intgration de vues personnalises dans nos listes, nous allons voir une dernire chose encore plus importante qui clturera ce chapitre : rajouter du dynamisme dans sa liste. V ous vous rendrez vite compte que nous avons rarement envie d'afficher toujours la mme chose sous la mme forme. Android a pens ce cas et nous permet facilement d'afficher plusieurs vues personnalises en fonction de nos dsirs.

Modification de l'adaptateur
Le but de notre nouveau adaptateur est de construire plusieurs types de vues avec une seule mthode (je vous laisse deviner laquelle ). Pour cet exemple, nous construisons deux vues que je nommerai DynamicHeaderListViewView et

www.siteduzero.com

Partie 1 : Fragmenter vos projets

23/79

DynamicBodyListViewView. La premire affiche une image gauche et du texte droite, la seconde affiche simplement du texte (comme la vue pour le sous-chapitre prcdent). Je vous laisse le bon soin de crer ses vues comme nous l'avons fait prcdemment. Cela ne devrait pas vous posez de problme. Le vritable changement se situe au niveau de notre adaptateur. Nous tendrons toujours BaseAdapter mais nous allons redfinir deux mthodes supplmentaires qui sont facultatives (j'entends par l qu'il n'est pas ncessaire de toujours les redfinir, seulement quand cela est ncessaire) : public int getViewTypeCount() et public int getItemViewType(int position). A quoi servent ces mthodes ? La premire nous demande combien de vues diffrentes seront prsentes dans notre liste. La seconde nous demande le type de vues pour la position courante dans la liste. Pour pouvoir complter ces mthodes, nous aurons besoin de constantes reprsentants les types de vues et une liste faisant correspondre chaque ligne de la liste avec son type associ. Si nous continuons notre exemple, avec le header et le body , nous aurons quelque chose qui ressemble ceci : Code : Java public class DynamicListViewAdapter extends BaseAdapter { private static final int TYPE_HEADER = 0; private static final int TYPE_BODY = 1; private static final int TYPE_MAX = 2; private List<Integer> mTypes = new ArrayList<Integer>(); // Autres attributs @Override public int getViewTypeCount() { return TYPE_MAX; } @Override public int getItemViewType(int position) { return mTypes.get(position); } } // Autres mthodes

La mise en place est aussi simple que cela. Il va maintenant falloir remplir la liste des types avec les lignes de la liste. Cela se fait naturellement dans les mthodes d'attachement. Nous en aurons deux : l'une pour l'en-tte de la liste et une seconde pour le corps de la liste. La premire mthode prend en paramtre un modle qui se trouve tre une classe confectionn par mes soins avec seulement 2 attributs reprsentant une image et un texte. La seconde mthode est identique la mthode vue au souschapitre prcdent, elle prendra une liste de chanes de caractres. Pour chacune de ces mthodes, nous ajouterons au fur et mesure les types dans la liste des types. Cela nous dera quelque chose comme ceci : Code : Java public class DynamicListViewAdapter extends BaseAdapter { // Autres attributs et mthodes public void bindHeader(DynamicListViewModel model) { mModelHeader = model; mTypes.add(TYPE_HEADER); } public void bindBody(List<Integer> model) { mModelBody = model; for (int i = 0; i < model.size(); i++) { mTypes.add(TYPE_BODY); } }

www.siteduzero.com

Partie 1 : Fragmenter vos projets

24/79

Nous avons aussi besoin de retoucher un peu nos anciennes mthodes. La taille de notre liste ne correspond plus la taille de notre liste de donnes. Il faut donc prvoir qu'un en-tte (ou pas) soit plac quelque part dans notre liste. Ainsi, nous modifions nos mthodes de la manire suivante : Code : Java public class DynamicListViewAdapter extends BaseAdapter { // Autres attributs et mthodes @Override public int getCount() { if (mModelHeader == null) return mModelBody.size(); return 1 + mModelBody.size(); } @Override public Object getItem(int position) { int type = getItemViewType(position); return type == TYPE_HEADER ? mModelHeader : mModelBody .get(position - 1); } } // Autres mthodes

Pour finir, nous avons notre mthode public View getView(int position, View convertView, ViewGroup parent) sur laquelle je vais vous laisser cogiter. V ous disposez de toutes les mthodes ncessaires pour mener bien sa confection. Si vous avez bien compris l'exemple prcdent avec une seule vue personnalise pour toute la liste, vous ne devriez pas avoir de mal en faire de mme pour plusieurs vues personnalises. Pensez simplement que les mthodes que nous avons redfinies ne sont sans doute pas l pour rien. Bien sr, ma solution se trouve cache ci-dessous. Secret (cliquez pour afficher) Code : Java package com.siteduzero.android.lists; import java.util.ArrayList; import java.util.List; import import import import android.content.Context; android.view.View; android.view.ViewGroup; android.widget.BaseAdapter;

public class DynamicListViewAdapter extends BaseAdapter { private static final int TYPE_HEADER = 0; private static final int TYPE_BODY = 1; private static final int TYPE_MAX = 2; private List<Integer> mTypes = new ArrayList<Integer>(); private DynamicListViewModel mModelHeader = null; private List<Integer> mModelBody = new ArrayList<Integer>(); private Context mContext; public DynamicListViewAdapter(Context context) { mContext = context; } @Override public int getViewTypeCount() { return TYPE_MAX; } @Override

www.siteduzero.com

Partie 1 : Fragmenter vos projets


public int getItemViewType(int position) { return mTypes.get(position); } @Override public int getCount() { if (mModelHeader == null) return mModelBody.size(); return 1 + mModelBody.size(); } @Override public Object getItem(int position) { int type = getItemViewType(position); return type == TYPE_HEADER ? mModelHeader : mModelBody .get(position - 1); } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { View v = null; int type = getItemViewType(position); if (convertView == null) { switch (type) { case TYPE_HEADER: v = new DynamicHeaderListViewView(mContext); break; case TYPE_BODY: v = new DynamicBodyListViewView(mContext); break; } } else { switch (type) { case TYPE_HEADER: v = (DynamicHeaderListViewView) convertView; break; case TYPE_BODY: v = (DynamicBodyListViewView) convertView; break; } } switch (type) { case TYPE_HEADER: DynamicListViewModel model1 = (DynamicListViewModel) getItem(position); ((DynamicHeaderListViewView) v).bind(model1.getImageRessource(), model1.getTextRessource()); break; case TYPE_BODY: Integer model2 = (Integer) getItem(position); ((DynamicBodyListViewView) v).bind(model2); break; } } return v;

25/79

public void bindHeader(DynamicListViewModel model) { mModelHeader = model; mTypes.add(TYPE_HEADER); }

www.siteduzero.com

Partie 1 : Fragmenter vos projets


public void bindBody(List<Integer> model) { mModelBody = model; for (int i = 0; i < model.size(); i++) { mTypes.add(TYPE_BODY); } }

26/79

Il n'en faut pas plus pour concevoir une liste dynamique. Il vous suffit ensuite d'intgrer ce nouvel adaptateur votre activit, en n'oubliant pas d'appeler les mthodes d'attachement pour remplir votre liste et vous devriez obtenir un rsultat similaire au mien :

www.siteduzero.com

Partie 1 : Fragmenter vos projets

27/79

Rsultat de l'excution d'une liste avec

plusieurs vues personnalises

www.siteduzero.com

Partie 1 : Fragmenter vos projets

28/79

PreferenceFragment
Depuis la version 3, Android met disposition des dveloppeurs des outils permettant de paramtriser facilement son application. En quoi consiste cette paramtrisation ? C'est simple. Il s'agit ni plus ni moins que des donnes partages dans toute l'application (que vous avez dj certainement utilis) mais intgrer dans une conception toute fait. Nous confectionnerons des fragments (ou des activits) qui auront comme seul objectif l'affichage des paramtres de la mme manire que ceux de votre smartphone. Cela va vous facilitez la vie mais je vous met en garde sur une petite chose. Nous utilisons depuis le dbut de ce tutoriel la bibliothque de compatibilit dvelopp par Google. Les prfrences ont galement t intgres dans cette bibliothque mais n'est pas trs performante (ou du moins, pas une grande chelle). Parce que le code est quand mme assez diffrent et pour ne pas tre limit, nous ne l'utiliserons pas pour ce chapitre. Mais sachez qu'il est possible de l'utiliser. Il faudra juste se renseigner un peu sur la faon de s'y prendre.

Paramtriser son application


Paramtriser son application par les prfrences du systme n'est pas obligatoire. V otre application n'a peut-tre pas besoin de sauvegarder quelque chose ou l'affichage des prfrences d'Android ne vous conviendra pas dans le design de votre application. Toutes ces choses sont vraies et en mme temps, c'est quelque chose de trs efficace et surtout qui ne dstabilisera pas l'utilisateur Android. Explications. Un utilisateur Android a l'habitude de se rendre dans les paramtres de son tlphone pour activer le Wi-Fi, le Bluetooth, le NFC, grer le son, la luminosit, etc. Toutes ces choses sont standardises (je mets cela entre guillemet parce que ce n'est pas vraiment le cas, c'est juste l'affichage normal sur les terminaux Android). Peu importe le lanceur d'application, le fond d'cran ou les widgets que vous placerez sur vos bureaux, les paramtres auront toujours le mme design. Il pourra en tre de mme pour votre application. L'utilisera saura directement comment l'utiliser et pour vous, cela sera du temps de dveloppement en moins.

Dfinir ses prfrences


La dclaration des composants d'un cran de prfrences est trs simple et se fait en grande partie partir d'un fichier XML. Ce fichier doit se trouver dans le dossier xml des ressources du projet et doit avoir comme racine un noeud de type PreferenceScreen. A partir de l, deux choix s'offrent vous. Soit vous dclarez des PreferenceCategory, dans ce cas, vous pourrez regrouper des prfrences. Soit vous dclarez directement des prfrences au risque d'tre brouillon si vous en avez beaucoup. PreferenceCategory doit contenir les attributs android:key et android:title pour pouvoir l'identifier et lui donner un titre. Il existe plusieurs types de prfrence. Avant tout, notez que vous devrez toujours donner une valeur aux attributs suivants : android:key pour pouvoir identifier les prfrences et en rcuprer sa valeur par la mmoire partage, android:title pour donner un nom la prfrence, android:summary pour donner des prcisions supplmentaires sur la prfrence et android:defaultValue pour donner une valeur par dfaut la prfrence. On retrouvera : CheckBoxPreference et SwitchPreference pour retenir un boolean en cochant la case cre ou non. EditTextPreference pour sauvegarder une chane de caractres. Il peut galement RingtonePreference pour saisir une sonnerie partir de votre terminal ou d'une application qui vous permet d'en tlcharger. Preference qui est une valeur non ditable par l'utilisateur. Cette prfrence change par une autre prfrence. Raison pour laquelle vous devez dclarer l'attribut android:dependency qui contiendra, comme valeur, la cl d'une autre prfrence. ListPreference est un peu spcial. V ous devez dfinir une liste de valeur dans lequel l'utilisateur pourra faire son choix. Pour ce faire, c'est simple. Il faut donner une valeur pour deux nouveaux attributs : android:entries pour donner un tableau de valeur qui sera affich l'utilisateur et android:entryValues pour afficher le code des valeurs de chaque ligne de ce tableau. Pour vous aidez mieux comprendre, ci-dessous se trouve un exemple complet pour dfinir ses prfrences reprenant toutes les notions que nous avons vu juste avant. Code : XML <?xml version="1.0" encoding="utf-8"?> <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" >

www.siteduzero.com

Partie 1 : Fragmenter vos projets


<PreferenceCategory android:key="pref_key_category_1" android:title="@string/title_category_1" > <CheckBoxPreference android:defaultValue="false" android:key="pref_key_pref_1" android:summary="@string/summary_pref_1" android:title="@string/title_pref_1" /> <Preference android:dependency="pref_key_pref_1" android:key="pref_key_pref_2" android:summary="@string/summary_pref_2" android:title="@string/title_pref_2" /> <SwitchPreference android:key="pref_key_pref_3" android:summary="@string/summary_pref_3" android:switchTextOff="@string/switch_off_pref_3" android:switchTextOn="@string/switch_on_pref_3" android:title="@string/title_pref_3" /> </PreferenceCategory> <PreferenceCategory android:key="pref_key_category_2" android:title="@string/title_category_2" > <EditTextPreference android:key="pref_key_pref_4" android:summary="@string/summary_pref_4" android:title="@string/title_pref_4" /> <ListPreference android:entries="@array/list_pref_5" android:entryValues="@array/list_pref_5" android:key="pref_key_pref_5" android:summary="@string/summary_pref_5" android:title="@string/title_pref_5" /> <RingtonePreference android:key="pref_key_pref_6" android:ringtoneType="ringtone" android:summary="@string/summary_pref_6" android:title="@string/title_pref_6" /> </PreferenceCategory> </PreferenceScreen>

29/79

www.siteduzero.com

Partie 1 : Fragmenter vos projets

30/79

Affichage des paramtres

Crer son fragment avec son activit


Il existe un fragment spcialement prvu pour accueillir les prfrences de votre application, PreferenceFragment. Il est alors enfantin de lui attacher notre fichier xml par un simple appel de mthode dans la mthode public void onCreate(Bundle savedInstanceState) : public void addPreferencesFromResource (int preferencesResId). Cette mthode prends une ressource en paramtre correspondant aux prfrences que vous voulez lies. En toute simplicit, notre fragment ressemblera : Code : Java

www.siteduzero.com

Partie 1 : Fragmenter vos projets


package com.siteduzero.android.settings; import android.os.Bundle; import android.preference.PreferenceFragment; import com.siteduzero.android.R; public class MyPreferenceFragment extends PreferenceFragment { public static final String TAG = "MyPreferenceFragment"; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); } addPreferencesFromResource(R.xml.preferences);

31/79

Affiner ses paramtres avec les en-ttes


Tout comme les catgories, les en-ttes ont pour objectif de rassembler des prfrences et de les structurer mais plus grande chelle. Une petite application aura rarement besoin d'utiliser le concept que je vais vous enseigner maintenant mais c'est une bonne chose connaitre parce que vous n'aurez peut-tre pas toujours des petites applications dvelopper. En fait, vous avez dj vu plusieurs fois des en-ttes. L'cran des paramtres de votre smartphone utilise les en-ttes simplement pour structurer la trs grande quantit de chose pouvoir paramtrer.

www.siteduzero.com

Partie 1 : Fragmenter vos projets

32/79

Affichage des paramtres du

smartphone

Dfinir les en-ttes


Je vous souponne de penser que dfinir tous ces en-ttes est quelque chose de long, compliqu et fastidieux. Je vous rpondrai cela que c'est quelque chose de rapide, simple et enfantin. Si vous avez dj des crans de prfrence et que vous voulez rajouter des en-ttes en cours de dveloppement, c'est tout aussi simple que de vouloir les rajouter ds le dbut du dveloppement de votre application. Tout comme la dfinition des prfrences, l'essentiel se passe dans un fichier XML qui se trouve toujours dans le dossier xml des ressources du projet et qui possde comme racine preference-headers. Aprs cela, il suffit de dclarer autant d'lment header que vous voulez d'en-tte. Celui-ci peut et doit dclarer remplir certains

www.siteduzero.com

Partie 1 : Fragmenter vos projets


attributs : android:fragment pour donner le chemin vers le fragment reprsentant l'cran de prfrence. android:icon pour ajouter une icone gauche de la prfrence (facultatif). android:summary pour ajouter des prcisions sur l'en-tte. android:title pour donner un titre l'en-tte. Un exemple simple exemple concret se trouve ci-dessous avec son rsultat l'excution de l'application.

33/79

Rsultat de l'excution des en-ttes

Attacher une activit


Les en-ttes sont attachs des activits qui hritent de PreferenceActivity mais elle ne redfinit pas la mthode

www.siteduzero.com

Partie 1 : Fragmenter vos projets

34/79

public void onCreate(Bundle savedInstanceState) comme le ferait toutes les autres activits. A la place, nous devrons redfinir la mthode public void onBuildHeaders(List<Header> target) pour y appeler la mthode suivante : public void loadHeadersFromResource (int resid, List<PreferenceActivity.Header> target). Cette mthode s'attend recevoir l'identifiant de la ressource des dclarations de vos en-ttes et la cible donn en paramtre votre mthode. En toute simplicit, nous arrivons au code suivant : Code : Java package com.siteduzero.android.settings; import java.util.List; import android.preference.PreferenceActivity; import com.siteduzero.android.R; public class SettingsActivity extends PreferenceActivity { @Override public void onBuildHeaders(List<Header> target) { loadHeadersFromResource(R.xml.header_preferences, target); } }

Lire les prfrences


Nous avons mis en place nos prfrences mais si nous n'utilisons pas les valeurs que nous paramtrisons, tout cela perdrait de son intrt. Android nous fournit un manager. V ous vous souvenez de ces managers dans le tutoriel de Apollidore o vous devez appeler la mthode public abstract Object getSystemService(String name) pour rcuprer le manager dont vous avez besoin pour faire des manipulations sur une certaine fonctionnalit ? Et bien, malheureusement pour vous, ce n'est pas la mme chose cette fois-ci ! En fait, c'est encore plus simple. Le manager est PreferenceManager et pour l'initialiser, vous aurez besoin d'appeler la mthode static public static SharedPreferences getDefaultSharedPreferences(Context context) qui renvoi un SharedPreferences (chose que vous devrez connatre). A partir de l, vous pourrez appeler des getters pour rcuprer les valeurs de vos prfrences partir des cls que vous avez donn. Un exemple trs simple ci-dessous avec son rsultat : Code : Java SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this); boolean pref1 = prefs.getBoolean("pref_key_pref_1", false); mTextViewPref1.setText("" + pref1); String pref2 = prefs.getString("pref_key_pref_2", "Nothing"); mTextViewPref2.setText("" + pref2); boolean pref3 = prefs.getBoolean("pref_key_pref_3", false); mTextViewPref3.setText("" + pref3); String pref4 = prefs.getString("pref_key_pref_4", "Nothing"); mTextViewPref4.setText("" + pref4); String pref5 = prefs.getString("pref_key_pref_5", "Nothing"); mTextViewPref5.setText("" + pref5); String pref6 = prefs.getString("pref_key_pref_6", "Nothing"); mTextViewPref6.setText("" + pref6);

www.siteduzero.com

Partie 1 : Fragmenter vos projets

35/79

Affichage des valeurs des paramtres

www.siteduzero.com

Partie 1 : Fragmenter vos projets

36/79

DialogFragment
Nous allons aborder la dernire notion utilisant les fragments partir de la version 3 d'Android, les DialogFragment. Ce composant nous permettra d'afficher une boite de dialogue l'utilisateur de manire beaucoup plus souple et plus complet que vous auriez pu le faire avec les anciens composants des versions infrieurs la 3.

Crer un DIalogFragment
V ous avez sans doute dj utiliser des AlertDialog ou des Dialog (surtout si vous avez lu le tutoriel d'Applidore). L'ide est de r-utiliser ce type de composant mais en lui attachant des fragments. C'est une pratique qui vous permettra de concevoir des boites de dialogue infiniment plus complexe et plus puissante que vos anciennes boites de dialogue. DialogFragment servira de conteneur notre fragment pour le transformer en boite de dialogue et ainsi fournir le style et la structure de la boite. Cette classe fournit tous les contrles ncessaires pour crer la boite et grer son apparence. Chose que nous apprendrons faire tout au long de ce chapitre ainsi que l'intgration de builder pour un autre type de boite. Pour commencer, nous allons procder comme chaque cration d'un type de fragment ; c'est--dire que nous allons tendre notre classe DialogFragment et redfinir un certains nombre de mthodes utiles l'intgration de notre fragment dans la boite et sa gestion. Pour ce faire, nous allons redfinir et dfinir les 2 mthodes suivantes : public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) : Pour dsrialiser le fichier XML reprsentant notre fragment et pour donner un titre notre boite de dialogue (ce dernier tant optionnel). public static MyDialogFragment newInstance() : Je reviendrais dans la seconde partie de ce tutoriel sur ce type de mthode mais sachez qu'elle nous permet d'encapsuler la cration de notre fragment et d'en connaitre des potentielles donnes. Ne vous tracassez pas la tte avec a maintenant, vous comprendrez bien assez tt son utilit. Nous obtenons donc le rsultat suivant : Code : Java package com.siteduzero.android.dialog; import import import import import import import android.os.Bundle; android.support.v4.app.DialogFragment; android.view.LayoutInflater; android.view.View; android.view.View.OnClickListener; android.view.ViewGroup; android.widget.Button;

import com.siteduzero.android.R; public class MyDialogFragment extends DialogFragment { public static MyDialogFragment newInstance(int title) { MyDialogFragment dialog = new MyDialogFragment(); Bundle args = new Bundle(); args.putInt("title", title); dialog.setArguments(args); return dialog; } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View v = inflater.inflate(R.layout.fragment_dialog, container, false); Button button = (Button) v.findViewById(R.id.buttonShow); button.setOnClickListener(new OnClickListener() { public void onClick(View v) { ((DialogActivity) getActivity()) .showDialogType(DialogActivity.TYPE_ALERT_DIALOG); } }); getDialog().setTitle(getArguments().getInt("title"));

www.siteduzero.com

Partie 1 : Fragmenter vos projets


} return v;

37/79

Chez moi (vous n'aurez pas le mme rsultat si le fichier XML est diffrent), le rsultat final intgr dans une FragmentActivity donnera le rsultat suivant :

Rsultat de l'excution des botes de

dialogue DialogFragment

Crer un AlertDialog
V ous tes cens savoir comment crer un AlertDialog. Je ne rentrerais donc pas dans les dtails en ce qui concerne sa cration mais beaucoup plus en ce qui concerne son intgration dans un fragment. En fait, c'est vraiment trs semblable au

www.siteduzero.com

Partie 1 : Fragmenter vos projets

38/79

DialogFragment et vous devrez avoir une petite ide de la manire de s'y prendre avec les connaissances que je viens de vous enseigner et vos connaissances prcdentes sur sa simple cration dans une Activity. Bien entendu, ce n'est pas exactement la mme chose. Nous n'allons pas devoir redfinir la mthode public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) mais public Dialog onCreateDialog(Bundle savedInstanceState). A partir de l, il nous suffit de retourner une AlertDialog avec l'aide d'un builder. La redfinition de la mthode donnera quelque chose comme : Code : Java @Override public Dialog onCreateDialog(Bundle savedInstanceState) { int title = getArguments().getInt("title"); return new AlertDialog.Builder(getActivity()) .setIcon(android.R.drawable.ic_dialog_alert) .setTitle(title) .setNegativeButton(R.string.alert_dialog_cancel, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int whichButton) { ((DialogActivity) getActivity()) .doNegativeClick(); } }) .setPositiveButton(R.string.alert_dialog_ok, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int whichButton) { ((DialogActivity) getActivity()) .doPositiveClick(); } }).create();

N'oubliez pas d'implmenter la mthode static pour crer une instance comme nous l'avons fait avec DialogFragment. Ainsi, nous obtenons le rsultat suivant :

www.siteduzero.com

Partie 1 : Fragmenter vos projets

39/79

Rsultat de l'excution des botes de

dialogue AlertDialog

Afficher une boite de dialogue


Dernire petite chose avant de terminer notre chapitre, nous allons rapidement voir comment intgrer nos boites de dialogue dans une activit. V ous comprendrez que ce n'est vraiment pas compliqu puisqu'il s'agit d'un fragment comme un autre. C'est la raison pour laquelle je vais vous laisser rflchir la question. Si vous avez bien compris la matire que je vous ai enseign dans les chapitres prcdents, cela ne devrait pas vous prendre trop longtemps. Sachez simplement que vous devez implmenter un certain nombre de mthode : public void doNegativeClick() : Appel lorsqu'on clique sur le bouton ngatif de l' AlertDialog. public void doPositiveClick() : Appel lorsqu'on clique sur le bouton positif de l'AlertDialog. public void showAlertDialog(View v) : Appel au clique de l'utilisateur sur le bouton de notre activit

www.siteduzero.com

Partie 1 : Fragmenter vos projets

40/79

destin l'affichage de l'AlertDialog. public void showDialogFragment(View v) : Appel au clique de l'utilisateur sur le bouton de notre activit destin l'affichage de DialogFragment. protected void showDialogType(int type) : Pour switcher dynamiquement entre les diffrentes botes de dialogue. Je vous laisse vos lignes de codes. V ous trouverez ma solution et son rsultat la suite de ce chapitre.

Correction
Code : Java package com.siteduzero.android.dialog; import import import import import import android.os.Bundle; android.support.v4.app.DialogFragment; android.support.v4.app.Fragment; android.support.v4.app.FragmentActivity; android.support.v4.app.FragmentTransaction; android.view.View;

import com.siteduzero.android.R; import com.siteduzero.android.dialog.alert.MyAlertDialog; public class DialogActivity extends FragmentActivity { public static final int TYPE_DIALOG_FRAGMENT = 1; public static final int TYPE_ALERT_DIALOG = 2; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_dialog); } protected void showDialogType(int type) { FragmentTransaction ft = getSupportFragmentManager().beginTransaction(); Fragment prev = getSupportFragmentManager().findFragmentByTag("dialog"); if (prev != null) { ft.remove(prev); } ft.addToBackStack(null); DialogFragment newFragment = null; switch (type) { case TYPE_DIALOG_FRAGMENT: newFragment = MyDialogFragment .newInstance(R.string.title_fragment_dialog); break; case TYPE_ALERT_DIALOG: newFragment = MyAlertDialog .newInstance(R.string.title_fragment_dialog_alert); break; } newFragment.show(ft, "dialog");

public void showDialogFragment(View v) { showDialogType(TYPE_DIALOG_FRAGMENT); } public void showAlertDialog(View v) { showDialogType(TYPE_ALERT_DIALOG); } public void doPositiveClick() { // TODO Do something

www.siteduzero.com

Partie 1 : Fragmenter vos projets


} public void doNegativeClick() { // TODO Do something }

41/79

Rsultat de l'excution de l'activit pour

afficher nos botes de dialogue

www.siteduzero.com

Partie 2 : Des nouveaux composants

42/79

Partie 2 : Des nouveaux composants


Aprs ce premier chapitre sur les fragments, vous aurez compris que la version 3 est un rel tournant dans le dveloppement d'application Android, que cela soit en terme d'architecture logicielle ou d'ergonomie. C'est vrai que cette version a apport normment au systme mais ce n'tait qu'un dbut, une premire bauche pour quelque chose d'encore plus gros. Cette version tait destine uniquement aux tablettes et la version 2.x coexistait comme alternative pour smartphone. Suite cela, Google a dvelopp la version 4 qui a pris le meilleur des deux mondes et qui en a fait un seul systme la fois compatible tablette et smartphone. Avec la venue de cette nouvelle version, l'utilisation des fragments est rest inchang (ouf, tout ce que je vous ai enseign jusqu' prsent n'aura pas servis rien) mais elle a ajoute une tonne de nouvelles choses. Certaines seront dj disponibles partir de la version 3 mais d'autres, comme le NFC, sont des exclusivits sur les terminaux Android 4 et plus.

La barre d'action des applications


La barre d'action d'une application est accessible qu' partir de la version 3 d'Android. Elle se caractrise par l'affichage d'un bandeau en haut de l'cran regroupant un certain nombre d'informations et pour y intgrer les menus. En fait, Google tente de diminuer les boutons physiques sur les terminaux le plus possible. Sur le march actuel, nous pouvons presque affirmer cette gnralit : les terminaux bas de prix possdent des touches physiques parce qu'ils tournent sur Android 2.3 et infrieur et les terminaux haut de gamme tournant sur Android 3 et plus ne possdent plus aucun bouton physique sur la face avant (ou trs peu). A la place, ils sont remplacs par des boutons tactiles en bas de l'cran et le menu est directement intgr dans le haut de l'cran dans les applications. C'est un choix auquel on adhre ou non. Personnellement, je prfre cette mthode.

Intgrer un menu
J'ai une bonne nouvelle pour vous, intgrer un menu dans une barre d'action est extrmement simple. Comme vous tes cens savoir comment crer des menus (sinon, je vous renvoie sur le tutoriel d'Apollidore sur les gestion des menus), il nous faudra que quelques modifications faire dans le fichier XML, c'est tout ! En effet, le systme dtectera automatiquement que vous lancez votre application sur un systme avec une version 3 ou suprieur d'Android et l'intgrera par dfaut. C'est plutt pratique ! V oici ce que nous allons faire : Nous allons crer un menu avec 4 items qui auront un identifiant, un titre et une icone. Cependant, nous allons rajouter une notion trs importante dans ces nouveaux menus, son affichage. En effet, un nouvel attribut est utilisable dans ces menus android:showAsAction. Cet attribut peut prendre une ou plusieurs valeurs parmi cette liste : ifRoom : Affichera l'item dans la barre d'action uniquement s'il y a encore de la place. withText : Affichera le texte du menu si le tlphone se trouve en mode paysage. never : N'affichera jamais l'item dans la barre d'action. always : Affichera l'item dans la barre d'action dans tous les cas. collapseActionView : Nous reviendrons sur cet attribut un peu plus tard dans ce chapitre. V ous devez savoir qu'il est possible de slectionner plusieurs des valeurs grce au pipeline | . Bien entendu, ne lui demander pas l'impossible, par exemple : never|always. Un exemple d'utilisation tout simple de nos 4 items se trouve la suite : Code : XML <?xml version="1.0" encoding="utf-8"?> <menu xmlns:android="http://schemas.android.com/apk/res/android" > <item android:id="@+id/menu_search" android:actionViewClass="android.widget.SearchView" android:icon="@android:drawable/ic_menu_search" android:showAsAction="always" android:title="@string/menu_search"/> <item android:id="@+id/menu_add" android:icon="@android:drawable/ic_menu_add" android:showAsAction="ifRoom|withText" android:title="@string/menu_add"/> <item android:id="@+id/menu_save" android:icon="@android:drawable/ic_menu_save" android:showAsAction="ifRoom|withText" android:title="@string/menu_save"/>

www.siteduzero.com

Partie 2 : Des nouveaux composants


<item android:id="@+id/menu_crop" android:icon="@android:drawable/ic_menu_crop" android:showAsAction="never" android:title="@string/menu_crop"/> </menu>

43/79

Nous afficherons donc dans tous les cas le menu de recherche, s'il y a de la place et avec son texte le menu d'ajout et de sauvegarde et nous n'afficherons jamais le redimensionnement dans la barre d'action mais dans un menu part qui s'affichera l'extrme droite de la barre. Du ct Java, rien ne change ! V ous continuez redfinir la mthode public boolean onCreateOptionsMenu(Menu menu) pour dsrialiser votre menu et public boolean onOptionsItemSelected(MenuItem item) pour ragir au clique sur l'un ou l'autre item du menu. Ceci nous donnera alors le rsultat suivant :

www.siteduzero.com

Partie 2 : Des nouveaux composants

44/79

Affichage des items du menu

Comme vous pouvez le constater, Android affiche notre item de recherche et d'ajout mais comme il n'y a plus de place pour la sauvegarde, il le place dans le sous menu accesible l'extrme droite de la barre.

Possibilits avances
La barre d'action, c'est sympa mais il est possible d'aller encore plus loin dans son utilisation. Nous ne verrons pas comment customiser cette barre. Cela prendrait un nouveau chapitre entier ce sujet et le design n'est pas le but de ce tutoriel. Cependant, si vous tes curieux ce sujet, Google a mis en place un site accessible via ce lien qui vous permettra de gnrer des styles tout faits. Il suffit alors de les intgrer vos projets. V ous devriez avoir les comptences pour le faire tout seul.

Barre de recherche
www.siteduzero.com

Partie 2 : Des nouveaux composants

45/79

Dans un premier temps, nous allons voir comment rendre notre item, destin effectuer une recherche, mieux intgr notre barre d'action (et ainsi comprendre quoi servira la dernire valeur du nouvel attribut sur les items du menu). L'ide est la suivante : Lorsque nous cliquerons sur la loupe, un champ de recherche prendra toute la place de la barre d'action (cachant les autres items du menu au passage) et affichant le clavier pour permettre l'utilisateur d'effectuer sa recherche dans votre application. Pour ce faire, nous aurons besoin d'effectuer des changements la fois du ct de l'XML et du ct Java. Du ct XML, nous allons rajouter un nouvel attribut android:actionViewClass. Il nous permet de spcifier un layout ou un widget utiliser. Dans notre cas, nous allons utiliser un widget dj integr au systme que nous r-utilisons. Nous modifions aussi android:showAsAction en rajoutant la valeur collapseActionView pour rendre notre vue pliable dans l'item du menu et ainsi la dplie tout le long de notre barre lorsque nous cliquons dessus. Ainsi, nous obtenons : Code : XML <item android:id="@+id/menu_search" android:actionViewClass="android.widget.SearchView" android:icon="@android:drawable/ic_menu_search" android:showAsAction="ifRoom|collapseActionView" android:title="@string/menu_search"/>

La modification du ct Java n'est pas ncessaire puisque si vous testez l'application comme a, vous aurez l'effet escompt. Cependant, il est fort utile de connaitre un listener qui s'attache ce type de vue OnQueryTextListener. Ce listener vous demandera d'implmenter deux mthodes : public boolean onQueryTextSubmit(String query) pour rcuprer la chane de caractre que l'utilisateur aura rentr lorsqu'il aura envoy la requte. public boolean onQueryTextChange(String newText) pour rcuprer la chane de caractre en cours lorsque l'utilisateur rentre un nouveau caractre ou en supprime. Ainsi, nous devons rcuprer notre item lors de la dsrialisation de notre menu et lui attacher notre listener via sa mthode public void setOnQueryTextListener (SearchView.OnQueryTextListener listener). V ous obtiendrez un rsultat similaire celui-ci : Code : Java @Override public boolean onCreateOptionsMenu(Menu menu) { MenuInflater inflater = getMenuInflater(); inflater.inflate(R.menu.menu_actionbar, menu); // SearchView MenuItem itemSearch = menu.findItem(R.id.menu_search); mSearchView = (SearchView) itemSearch.getActionView(); mSearchView.setOnQueryTextListener(new OnQueryTextListener() { @Override public boolean onQueryTextSubmit(String query) { Toast.makeText(getApplicationContext(), R.string.toast_search_submit, Toast.LENGTH_SHORT) .show(); return true; } @Override public boolean onQueryTextChange(String newText) { return false; } }); } return true;

www.siteduzero.com

Partie 2 : Des nouveaux composants

46/79

Affichage de la barre de recherche dans

la barre d'action

Partage travers le systme


Une autre astuce avec la barre d'action est le partage travers le systme. V ous le savez maintenant, l'une des forces d'Android est la possibilit aux applications de dialoguer un minimum entre elles. Du coup, il est normal pour les applications de vouloir partager du contenu avec toutes les applications du systme susceptibles de pouvoir faire l'affaire. Google a pens cela en intgrant une solution toute faite qui convient parfaitement se retrouver dans la barre d'action, le ShareActionProvider. Cette fois-ci, la majeur partie se ferra du ct Java. Nous avons simplement besoin, du ct XML, de rajouter un item destin au partage avec un attribut android:actionProviderClass qui renseigne la valeur android.widget.ShareActionProvider.

www.siteduzero.com

Partie 2 : Des nouveaux composants


Aprs quoi, nous pouvons rcuprer l'item dans la mthode qui dsrialise notre menu pour lui dire quoi faire.

47/79

Ce que nous voulons est trs simple. Rcuprer l'item et lui demander quoi partager avec l'aide de la mthode public void setShareIntent (Intent shareIntent). Dans l'exemple qui suit, nous avons decider de partager simplement du texte mais cela aurait pu tre n'importe quoi d'autres qu'un Intent supporte (image, fichier, etc.). Nous obtenons alors la mthode suivante : Code : Java @Override public boolean onCreateOptionsMenu(Menu menu) { MenuInflater inflater = getMenuInflater(); inflater.inflate(R.menu.menu_actionbar, menu); // ShareActionProvider MenuItem itemProvider = menu.findItem(R.id.menu_share); mShareActionProvider = (ShareActionProvider) itemProvider.getActionProvider(); Intent intent = new Intent(Intent.ACTION_SEND); intent.setType("text/plain"); intent.putExtra(Intent.EXTRA_TEXT, "Message"); mShareActionProvider.setShareIntent(shareIntent); } return true;

www.siteduzero.com

Partie 2 : Des nouveaux composants

48/79

Affichage des fournisseurs de partage

Spliter le menu
V ous savez sans doute de quoi je parle, l'application de messagerie du systme Android l'utilise dans son application. L'ide est de sparer le menu de la barre d'action dans une nouvelle barre situ en bas de l'cran. Cela nous permettra de mettre plus d'item visible l'utilisateur et de dissocier la barre d'action du menu. En contre partie, nous perdons de la place sur l'cran. Sa mise en place est extrmement simple puisqu'il suffit de rajouter l'attribut et la valeur android:uiOptions="splitActionBarWhenNarrow" dans l'activit contenant le menu que vous voulez diviser dans le fichier Manifest.

www.siteduzero.com

Partie 2 : Des nouveaux composants

49/79

Affichage de la division du menu la

barre d'action

Bouton home
Dernire petite chose, l'icone en haut gauche de votre cran peut galement servir comme un bouton. Il est gnralement utilis pour revenir en arrire (comme un bouton back) ou l'cran d'accueil de votre application (justement pour ne pas tre redondant au bouton back) mais vous pouvez l'utiliser comme bon vous semble. Je vous conseil quand mme de l'utiliser cet usage afin que les utilisateurs Android ne soient pas dbousolls lorsqu'ils utilisent votre application. Pour ce faire, vous devez rcuprer la barre d'action grce la mthode public ActionBar getActionBar() et apperler la mthode public abstract void setDisplayHomeAsUpEnabled (boolean showHomeAsUp)

www.siteduzero.com

Partie 2 : Des nouveaux composants

50/79

dessus en lui donnant la valeur true. V otre icone aura alors une petite flche gauche de l'icone qui vous indiquera que vous pouvez cliquer dessus (voire les captures d'cran ci-dessus). Code : Java @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); ActionBar actionBar = getActionBar(); actionBar.setDisplayHomeAsUpEnabled(true);

Un identifiant lui est automatiquement assign par le systme que vous pourrez tester dans la mthode public boolean onOptionsItemSelected(MenuItem item) et qui es R.id.home.

Menu contextuel

V ous vous rappelez des anciens menus contextuels ? Malheureusement, c'est une pratique qui peut encore tre utilise dans les applications actuelles mais qui ne sont pas du tout ergonomiques. V ous tes oblig de presser un certain temps sur un lment avec votre doigt pour voir apparaitre votre menu. Google a rflchi cette problmatique et a trouv une solution plutt lgante. Nous allons profiter de la barre d'action pour afficher un menu intermdiaire qui apparaitra quand bon vous semble (j'entends par l qu'il n'est pas ncessaire de rester appuy sur un lment pour faire apparaitre le menu). D'ailleurs, dans notre exemple, nous l'afficherons lorsque l'utilisateur cliquera sur un bouton pour bien diffrencier ce type de menu avec l'ancien mais sachez qu'il est toujours possible de le faire avec l'ancienne mthode. Nous dclarons un nouveau fichier XML destin tre notre menu intermdiaire. Nous le dclarons comme un menu normal, nous n'avons rien faire en plus de ce ct. Tout se jouera dans la partie Java. V ous tes maintenant cens savoir comment dclarer ce genre de choses, je vous laisse donc ce plaisir. Dans notre fichier XML d'affichage, nous dclarons un bouton avec un attribut android:onClick qui prendra la valeur changeContextual. Si vous ne connaissez pas cet attribut, il vous permet d'assigner une mthode de votre Activity votre bouton que vous avez spcifi. La mthode dsigne par cet attribut doit tre sous la sous la forme public void nomDeLaMethode(View view). Sinon, votre application plantera.

Nous voulons simplement afficher le menu contextuel, nous allons donc appeler la mthode public ActionMode startActionMode (ActionMode.Callback callback) sur l'activit. Cette mthode lancera l'affichage du menu grce au paramtre que vous lui donnez en paramtre. Ce paramtre prend une implmentation d'une interface Callback appartenant ActionMode. Son implmentation exige 4 mthodes redfinir : public boolean onActionItemClicked(ActionMode mode, MenuItem item) pour rcuprer l'item sur lequel l'utilisateur a cliqu. public boolean onCreateActionMode(ActionMode mode, Menu menu) pour dsrialiser votre fichier XML contenant votre menu. public void onDestroyActionMode(ActionMode mode) appel lorsque votre menu est dtruit (lorsqu'il n'est plus affich l'cran). public boolean onPrepareActionMode(ActionMode mode, Menu menu) appel lorsqu'on tente de rafraichir le menu avec une mthode invalidate. Pour rester simple, nous allons simplement donner une implmentation aux deux premires mthodes qui fonctionnent exactement comme les menus normaux ! Nous obtenons alors une Activity semble au code ci-dessous et au rsultat suivant : Code : Java package com.siteduzero.android.actionbar; import android.app.Activity; import android.os.Bundle; import android.view.ActionMode;

www.siteduzero.com

Partie 2 : Des nouveaux composants


import import import import import android.view.Menu; android.view.MenuInflater; android.view.MenuItem ; android.view.View; android.widget.Toast;

51/79

import com.siteduzero.android.R; public class ActionBarContextualActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_contextual); } public void changeContextual(View view) { startActionMode(new ActionMode.Callback() { @Override public boolean onActionItemClicked(ActionMode mode, MenuItem item) { switch (item.getItemId()) { case R.id.menu_trash: Toast.makeText(getApplicationContext(), R.string.toast_trash, Toast.LENGTH_SHORT).show(); return true; } return false; } @Override public boolean onCreateActionMode(ActionMode mode, Menu menu) { MenuInflater inflater = mode.getMenuInflater(); inflater.inflate(R.menu.menu_contextual, menu); return true; } @Override public void onDestroyActionMode(ActionMode mode) { } @Override public boolean onPrepareActionMode(ActionMode mode, Menu menu) { return false; } });

www.siteduzero.com

Partie 2 : Des nouveaux composants

52/79

Affichage du menu contextuel

Mais alors, cela voudrait dire que nous pouvons crer plusieurs menus contextuels pour une seule classe ?

V ous avez tout compris. V ous pourriez crer plusieurs menus contextuels en fonction de la situation. C'est l'une des forces de ce type de menu et une excellente alternative l'ancienne manire de faire !

www.siteduzero.com

Partie 2 : Des nouveaux composants

53/79

Slider travers des crans


Maintenant que nous savons comment utiliser les fragments, nous allons pouvoir nous amuser un peu ! Confectionner des interfaces ergonomiques et originales. Si vous vous rappelez de notre premire utilisation des fragments dynamiques, nous avons simul le slide d'un cran l'autre lanc par un bouton. C'tait pas mal mais nous allons maintenant voir le slide travers vos crans grce un swipe. V ous verrez, Android nous simplifie grandement la tche grce au widget ViewPager. Le swipe est une gesture. C'est l'action de passer votre doigt de gauche droite et inversement sur l'cran de votre terminal.

Passer des informations la cration d'un fragment


Avant de commencer utiliser le widget ViewPager, nous allons voir comment passer des informations la cration d'un fragment via un Bundle. C'est quelque chose de ncessaire pour ce chapitre. Mme si vous tes cens savoir comment on manipule des Bundle grce aux Intent, son utilisation est lgrement diffrente avec les fragments. Si vous ne savez plus comment confectionner des fragments, je vous renvoie au premier chapitre de la partie 1 o les fragments sont abords de manire dtaills. V ous savez comment confectionner des fragments et jusqu' prsent, il vous a fallu les dclarer soit dans un fichier XML d'affichage que vous dsrialisez dans une classe Fragment soit crer des instances de vos fragments que vous affichez dynamiquement via l'API destin la gestion des fragments. Mais qu'arriverait-il si vous deviez chaque fois passez un Bundle la cration d'un Fragment. V ous devriez rpter constamment la manipulation partout dans votre code. Est-ce qu'il n'y aurait pas moyen d'encapsuler cette pratique quelque part pour une meilleur maintenance de votre code et pouvoir le modifier de manire plus efficace (sinon, vous devriez changer chaque endroit o vous crez vos instances. Tant que cela reste un petit projet, a va mais cela pourrait vite grimper). Qu'allons-nous faire ? Nous allons rajouter une mthode static dans notre Fragment. Cette dernire nous permettra de crer une instance de notre fragment et d'encapsuler toutes les informations que nous aurons besoin dans notre fragment. Cette mthode sera donc sous la forme du code ci-dessous pour un Fragment portant le nom DummyFragment. Code : Java public static DummyFragment newInstance(/* informations que je veux donner mon fragment */) { // renvoie une instance de mon fragment }

Je vous rappelle que static signifie que la mthode n'est pas directement attache aux instances que vous crez de la classe dans laquelle la mthode est retenue. Par exemple, vous pouvez donc y crer des instances de la classe dans laquelle vous tes. Maintenant, imaginons que nous voulons donner une chane de caractres notre Fragment pour l'afficher dans un TextView qu'il contient. L'ide est de crer un Bundle qui va contenir une chane de caractres avec une cl que nous dfinirons pour le rcuprer par la suite dans la cration de l'interface du fragment ; c'est--dire dans sa mthode public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState). Dans un premier temps, nous allons remplir notre mthode static pour attacher un Bundle notre fragment. Cela se fait trs simplement avec la mthode public void setArguments(Bundle args) : Code : Java public static DummyFragment newInstance(String chaine) { DummyFragment fragment = new DummyFragment(); Bundle args = new Bundle(); args.putString("KEY_STRING", chaine); fragment.setArguments(args); return fragment; }

C'est aussi simple que cela. Nous crer une instance de notre Fragment, on cre un bundle dans lequel nous placons notre chane de caractres, nous l'attachons notre Fragment et nous le renvoyons. Pour rcuprer ce Bundle, c'est tout aussi simple. Le setter des arguments de notre fragment possde galement un getter. Nous pouvons donc trs simplement rcuprer

www.siteduzero.com

Partie 2 : Des nouveaux composants

54/79

le Bundle grce la mthode public final Bundle getArguments(). Ainsi, notre mthode public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) ressemblera : Code : Java @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { TextView textView = new TextView(getActivity()); textView.setGravity(Gravity.CENTER); Bundle args = getArguments(); textView.setText(args.getString("KEY_STRING")); return textView; }

V ous l'avez sans doute remarqu mais je n'ai pas utilis de fichier XML d'affichage pour mon Fragment. L'XML est une pratique que j'encourage mais dans le cadre de cet exemple, pour rester simple, j'ai prfr crer dynamiquement un TextView pour afficher notre chane de caractres. C'est tout ! Grce cette mthode, vous crez vos fragments grce la mthode static et l'affichage de ce dernier, vous verrez la chane de caractres (ou n'importe quelle information que vous lui avez donn) l'cran.

Utilisation du widget ViewPager L'adaptateur du ViewPager


Bien, nous allons pouvoir commencer les choses srieuses ! ViewPager est en fait un conteneur comme ListView, GridView, etc. sauf qu'il ne s'utilise pas avec le mme type d'adaptateur. Le ViewPager est conu pour fonctionner seulement avec des Fragment et rien d'autres. Ainsi, son adaptateur ne possde pas une mthode View getView(...) qui renvoie une View avec votre conteneur. C'est beaucoup plus simple que cela ! Notre adaptateur devra tendre FragmentPagerAdapter. Cette classe nous imposera d'implmenter 1 constructeur et 2 mthodes : public ViewPagerAdapter(FragmentManager fm) est le constructeur impos puisque votre adaptateur devra renvoyer la super classe une instance d'un FragmentManager. public Fragment getItem(int pos) pour rcuprer une instance du fragment en cours. public int getCount() pour connatre le nombre de fragments que devra contenir notre ViewPager. Si vous avez bien compris le sous-chapitre prcdent, vous aurez compris que nous appellerons les mthodes static de nos fragments dans la mthode public Fragment getItem(int pos). C'est lui qui est charg de renvoyer les instances des fragments contenus dans notre conteneur. Je vais maintenant vous laissez rflchir la ralisation de notre adaptateur. Je veux que : V ous utilisez le fragment que nous avons utilis dans le sous-chapitre prcdent; V ous affichez 3 fois le mme fragment; V ous attachez 3 chanes de caractres diffrentes en fonction de la position. Comme d'habitude, vous retrouverez ma correction ci-dessous.

Correction
Code : Java package com.siteduzero.android.viewpager; import android.support.v4.app.Fragment; import android.support.v4.app.FragmentManager; import android.support.v4.app.FragmentPagerAdapter; import com.siteduzero.android.R; public class ViewPagerAdapter extends FragmentPagerAdapter { public ViewPagerAdapter(FragmentManager fm) {

www.siteduzero.com

Partie 2 : Des nouveaux composants


} super(fm);

55/79

@Override public Fragment switch(pos) { case 1: return !"); case 2: return !"); case 3: return cran !"); } return null; }

getItem(int pos) { DummyFragment.newInstance("Je suis le premier cran DummyFragment.newInstance("Je suis le second cran DummyFragment.newInstance("Je suis le troisime

@Override public int getCount() { return 3; }

Activit du ViewPager
Nous avons notre Fragment, notre adaptateur, il nous manque plus que notre activit. Pour une fois, notre fichier XML d'affichage aura une petite particularit. Nous allons dclarer simplement un ViewPager sa racine mais pour des soucis de compatibilit, notre conteneur est galement redfini dans le projet v4 que nous utilisons depuis le dbut de ce tutoriel. Pour ce faire, le nom de l'lement sera accessible par le chemin android.support.v4.view et nous donnera donc la dclaration suivante : Code : XML <android.support.v4.view.ViewPager xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/viewPager" android:layout_width="match_parent" android:layout_height="match_parent" />

Du ct de notre Activity, c'est exactement pareil qu'avec les autres conteneurs. A la diffrence que nous n'tendrons pas Activity mais FragmentActivity. Cela nous donnera donc le code et le rsultat suivant : Code : Java package com.siteduzero.android.viewpager; import import import import android.app.FragmentTransaction; android.os.Bundle; android.support.v4.app.FragmentActivity; android.support.v4.view.ViewPager;

import com.siteduzero.android.R; public class ViewPagerActivity extends FragmentActivity { private ViewPagerAdapter mSectionsPagerAdapter; private ViewPager mViewPager; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_viewpager); // Set up the adapter. mSectionsPagerAdapter = new ViewPagerAdapter(getSupportFragmentManager());

www.siteduzero.com

Partie 2 : Des nouveaux composants


// Set up the ViewPager with the sections adapter. mViewPager = (ViewPager) findViewById(R.id.viewPager); mViewPager.setAdapter(mSectionsPagerAdapter);

56/79

Affichage du premier cran de notre

ViewPager

Ajout d'un indicateur de la page


Nous savons maintenant comment mettre en place un ViewPager mais il arrive que nous voulons savoir quelle page nous

www.siteduzero.com

Partie 2 : Des nouveaux composants


nous trouvons. Pour cela, Android a prvu une solution trs lgante integr directement dans la barre d'action de votre application. Pour ce faire, nous ne devrons pas toucher du tout nos fragment, notre adaptateur ni notre fichier XML d'affichage. Tout se passe uniquement dans l'activit qui dsrialise votre ViewPager. L'ide est la suivante : Nous allons indiquer notre barre d'action qu'il navigera via des Tabs . A chaque changement de page, il faut indiquer notre indicateur de changer le focus. Lorsqu'on slectionne une tab, nous devons changer la page du ViewPager. V oici comment procder :

57/79

Navigation en tab
Pour indique que nous comptons utiliser les tabs de la barre d'action, nous devons rcuprer notre barre d'action et appeler dessus la mthode public abstract void setNavigationMode(int mode). Cette mthode prend en paramtre un mode qui se retrouve comme constante dans la classe ActionBar : NAVIGATION_MODE_STANDARD : Valeur par dfaut de votre barre d'action. Consiste afficher votre logo ou icone et le texte avec un sous titre optionnel dans la barre d'action. NAVIGATION_MODE_LIST : Change le titre prsent dans la barre d'action en une liste droulante que vous pouvez drouler lorsque vous cliquez dessus. NAVIGATION_MODE_TABS : V ous permettra d'utiliser des tabs dans votre barre d'action. Ainsi, dans notre mthode public void onCreate(Bundle savedInstanceState) de notre Activity, nous faisons la manipulation suivante : Code : Java @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // Set up others things // Set up the action bar. final ActionBar actionBar = getActionBar(); actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS); } // Set up others things

Modifier l'indicateur
Pour modifier l'indicateur en fonction de la page courante de l'utilisateur sur le ViewPager, nous allons devoir attacher un listener notre conteneur via la mthode public void setOnPageChangeListener(ViewPager.OnPageChangeListener listener). Le lisener OnPageChangeListener impose d'implmenter 3 mthodes : public abstract void onPageScrollStateChanged(int state): Appel lorsque l'tat du dfilement change. public abstract void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) : Appel lorsque la page courante est en train d'tre modifi. public abstract void onPageSelected(int position) : Appel lorsqu'une nouvelle page est slectionne. La dernire mthode est celle qui nous intresse puisqu'elle nous indique la position dans laquelle nous nous trouvons dans le conteneur. Ainsi, nous pouvons appeler la mthode public abstract void setSelectedNavigationItem(int position) sur la barre d'action et obtenir le rsultat suivant : Code : Java @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState);

www.siteduzero.com

Partie 2 : Des nouveaux composants


setContentView(R.layout.activity_viewpager); // Set up others things // Set up the gesture to swipe between tab. mViewPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() { @Override public void onPageSelected(int position) { actionBar.setSelectedNavigationItem(position); } }); } // Set up others things

58/79

V ous remarquez sans doute que je n'implmente pas les 3 mthodes. C'est simplement grce ViewPager.SimpleOnPageChangeListener qui est un listener alternatif qui me permet de redfinir uniquement les mthodes que je veux redfinir. C'est bien pratique mais il est ncessaire d'avoir une petite ide des mthodes accessibles.

Modifier la page
Pour finir, nous voulons faire l'inverse, nous voulons modifier la page courante du conteneur lorsque nous cliquons sur l'un des tabs de notre activit. Pour ce faire, nous devons faire plusieurs choses : A la dclaration de nos tabs, nous allons attacher chaque tab le mme listener qui va s'occuper de changer la page courante de notre ViewPager. Pour ce faire, nous allons implmenter au niveau de l'activit, la classe ActionBar.TabListener. Elle nous oblige alors implmenter 3 mthodes : public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) : Appel lorsqu'un tab n'est plus slectionn. public void onTabSelected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) : Appel lorsqu'un tab est slectionn. public void onTabReselected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) : Appel lorsqu'un tab est reslectionn. On implmentera donc la seconde mthode de la manire suivante : Code : Java @Override public void onTabSelected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) { mViewPager.setCurrentItem(tab.getPosition()); }

Nous pouvons maintenant crer nos tabs grce trois mthodes que nous appellerons sur une instance de notre barre d'action : public abstract void addTab(ActionBar.Tab tab) : Mthode pour ajouter un tab l'activit. public abstract ActionBar.Tab newTab() : Mthode pour crer un tab. public abstract ActionBar.Tab setTabListener (ActionBar.TabListener listener) : Mthode pour attacher un listener notre tab. Nous utiliserons donc ces mthodes de la manire suivante : Code : Java @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_viewpager); // Set up other things // For each of the sections in the app, add a tab to the action bar.

www.siteduzero.com

Partie 2 : Des nouveaux composants


for (int i = 0; i < mSectionsPagerAdapter.getCount(); i++) {

59/79

actionBar.addTab(actionBar.newTab().setText(mSectionsPagerAdapter.getPageTitle(i)). } }

V ous avez sans doute remarqu la mthode public CharSequence getPageTitle(int position) appel sur notre adaptateur. Cette mthode est en fait une mthode optionnel implmenter qui nous permettra de contenir l' intelligence pour le choix du titre de nos pages. V ous n'tes pas oblig de recourir cette mthode, c'est juste un plus que je vous offre. Ceci nous donnera alors le rsultat suivant en mode portrait et paysage :

www.siteduzero.com

Partie 2 : Des nouveaux composants

60/79

Affichage du ViewPager avec une barre

d'indicateur en portrait

www.siteduzero.com

Partie 2 : Des nouveaux composants

61/79

Affichage du ViewPager avec une barre d'indicateur en paysage

www.siteduzero.com

Partie 2 : Des nouveaux composants

62/79

Notifier l'utilisateur
Les notifications, cela ne devrait pas tre un nouveau concept. V ous en avez dj dvelopp et cela vous certainement bien servi dans vos applications. Cependant, la construction des notifications a chang depuis Android 3 et de nouvelles notifications sont apparus avec Android 4.1. Ce chapitre est donc destin uniquement vous enseignez comment construire ces nouvelles notifications sans parler de services et autres endroits o vous tes cens lancer vos notifications. Ces choses ont t abordes dans le tutoriel de Apollidore.

Basique
La cration de notifications se fait maintenant par l'intermdiaire d'un service systme, chose que vous devriez bien connatre puisqu'une grande partie des services du systme sont grs de cette manire. Il vous faudra donc en rcuprer une instance grce l'instruction suivante : Code : Java mNotificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);

Maintenant que vous savez cela, nous pouvons commencer l'apprentissage de notre premire notification basique. Ce type de notification est la seule pouvant tre lance sur les terminaux Android 3 et plus. Aprs cela, tous les autres types plus complexes seront apparus avec la version 4.1 d'Android. Cependant, grce au projet de compatibilit v4 que nous utilisons constamment dans ce tutoriel, ce procd est accessible aux versions plus anciennes que la version 3. Par contre, les nouveaux concepts de la version 4.1 seront ignors si vous construisez ces types de notifications ; c'est--dire que vous pouvez construire des notifications complexes qui s'afficheront correctement sur la version 4.1 et suprieur mais qui paraitront comme de simples notifications sur les autres versions. C'est un bon compromis pour rester compatible avec les anciennes versions mais il faut garder cet aspect l'esprit. Dans un premier temps, nous aurons besoin d'un Builder spcifique aux notifications. Il est accessible par la classe Notification et s'initialise avec son constructeur en lui passant un contexte en paramtre : Code : Java Builder builder = new NotificationCompat.Builder(this);

A partir de cette instance, nous allons construire et rcuprer une instance de la classe Notification. Pour la construire, nous avons accs une petite srie de mthodes : public NotificationCompat.Builder votre notification. public NotificationCompat.Builder votre notification. public NotificationCompat.Builder notification. public NotificationCompat.Builder votre notification. setContentTitle(CharSequence title) : Donne un titre setContentText(CharSequence text) : Donne un texte setSmallIcon(int icon) : Donne une icne votre setWhen(long when) : Donne un timestamp pour l'affichage de

Ce n'est pas toutes les mthodes possibles disponibles partir d'Android 3, elles sont trop nombreuses et ce tutoriel n'est pas destin devenir une documentation. Si vous voulez en savoir plus, je vous renvoie sur la documentation Android. Aprs quoi, nous initialiserons les flags comme vous le faisiez avec les prcdentes notifications et nous la lanons grce la mthode public void notify(int id, Notification notification) sur notre service systme. Ce dernier prenant en paramtre l'identifiant de la notification et l'object comportant votre notification. Nous obtenons donc le code source et le rsultat suivant : Code : Java Builder builder = new NotificationCompat.Builder(this); Notification notification = builder .setContentTitle(getResources().getText(R.string.basic_title))

www.siteduzero.com

Partie 2 : Des nouveaux composants


.setContentText(getResources().getText(R.string.basic_text)) .setSmallIcon(R.drawable.ic_launcher) .setWhen(System.currentTimeMillis()).build(); notification.flags |= Notification.FLAG_AUTO_CANCEL; mNotificationManager.notify(0, notification);

63/79

Excution de la notification basique

Les diffrents styles


Les nouvelles notifications sont vues comme des nouveaux styles. Au nombre de 3, vous aurez la possibilit de : Afficher un grand texte dans votre notification. Afficher une grande image dans votre notification.

www.siteduzero.com

Partie 2 : Des nouveaux composants


Afficher une liste de chanes de caractres dans votre notification.

64/79

Grand texte
Abordons les nouvelles notifications avec un grand texte. Il faut savoir que vous tes limit en caractres si vous utilisez la mthode public NotificationCompat.Builder setContentText(CharSequence text). Elle s'affichera toujours sur une seule ligne uniquement. Ce n'est donc pas du tout optimis si, pour une raison X ou Y , vous dsirez crire plus. Cette nouvelle notification rgle le problme trs facilement et par l'intermdiaire d'une nouvelle classe, NotificationCompat.BigTextStyle, que vous devrez initialiser en passant un NotificationCompat.Builder en paramtre. V ous construisez donc votre builder de la mme manire que la notification basique, en omettant la mthode public NotificationCompat.Builder setContentText(CharSequence text) naturellement, et vous rcuprez un objet NotificationCompat.BigTextStyle en lui passant ce builder en paramtre de son constructeur. A partir de cet objet, vous pouvez appelez 3 mthodes diffrentes : public NotificationCompat.BigTextStyle bigText(CharSequence cs) : Afficher un grand texte pour votre notification. public NotificationCompat.BigTextStyle setBigContentTitle(CharSequence title) : Afficher un grand titre pour votre notification. public NotificationCompat.BigTextStyle setSummaryText(CharSequence cs) : Afficher un petit texte la fin de votre notification destin la rsum. Sachez que dans les 3 styles, les deux dernires mthodes seront toujours disponibles.

Une fois termin, vous appelez la mthode public Notification build () qui vous construira la notification que vous pourrez lancer. Ainsi, nous obtenons le code source et le rsultat suivant en utilisant simplement la premire des 3 mthodes disponibles pour NotificationCompat.BigTextStyle : Code : Java Builder builder = new NotificationCompat.Builder(this); builder.setContentTitle(getResources().getText(R.string.big_text_title)) .setSmallIcon(R.drawable.ic_launcher); BigTextStyle bigTextStyle = new NotificationCompat.BigTextStyle(builder); bigTextStyle.bigText(getResources().getText(R.string.big_text)); Notification notification = bigTextStyle.build(); notification.flags |= Notification.FLAG_AUTO_CANCEL; mNotificationManager.notify(0, notification);

www.siteduzero.com

Partie 2 : Des nouveaux composants

65/79

Excution de la notification affichant un

grand texte Remarquez que j'ai utilis le mme indice pour cette notification et celle de la sous-partie prcdente. Cela permettra Android de rcuprer une notification (si elle est construite) plutt que d'en crer une nouvelle. C'est une bonne pratique lorsque vous concevez des applications Android. Tentez de la respecter le plus possible.

Grande image
La grande image est trs similaire la notification avec un grand texte, c'est pourquoi je vais vous laisser rflchir la faon de faire pour lancer ce type de notifications. Sachez simplement que vous allez devoir utiliser la classe

www.siteduzero.com

Partie 2 : Des nouveaux composants


NotificationCompat.BigPictureStyle. V ous devriez avoir un rsultat similaire au mien (sachant que je vous demande pas de trouver l'image exacte que j'utilise ).

66/79

Excution de la notification affichant une

grande image

Correction
Sans surprise, je pense que vous tes arriv aisment au mme rsultat que moi : Code : Java Builder builder = new NotificationCompat.Builder(this);

www.siteduzero.com

Partie 2 : Des nouveaux composants


builder.setContentTitle(getResources().getText(R.string.big_pic_title)) .setSmallIcon(R.drawable.ic_launcher); BigPictureStyle bigPic = new NotificationCompat.BigPictureStyle(builder); Notification notification = bigPic.bigPicture( BitmapFactory.decodeResource(getResources(), R.drawable.notif_big_pic)).build(); notification.flags |= Notification.FLAG_AUTO_CANCEL; mNotificationManager.notify(0, notification);

67/79

Liste de chanes de caractres


Continuons sur notre lance puisque le dernier style est aussi trs similaire aux deux autres. Nous allons confectionner une notification qui va afficher deux lignes et un message en fin de notification qui va rcapituler le nombre de lignes dans la notification. Sachez simplement que vous allez devoir utiliser la classe NotificationCompat.InboxStyle. Nous aurons donc le rsultat suivant :

www.siteduzero.com

Partie 2 : Des nouveaux composants

68/79

Excution de la notification affichant une

liste

Correction
Code : Java Builder builder = new NotificationCompat.Builder(this); builder.setContentTitle(getResources().getText(R.string.inbox_title)) .setSmallIcon(R.drawable.ic_launcher); InboxStyle inbox = new NotificationCompat.InboxStyle(builder); Notification notification = inbox.addLine("Line 1").addLine("Line 2") .setSummaryText("You have 2 messages").build();

www.siteduzero.com

Partie 2 : Des nouveaux composants


notification.flags |= Notification.FLAG_AUTO_CANCEL; mNotificationManager.notify(0, notification);

69/79

Ajouter des boutons d'action


Une chose qui n'est pas integre dans les exemples prcdents est la possibilit de rajouter des boutons d'action vos notifications. C'est--dire qu'il est possible d'ajouter des boutons sous votre notification qui vous permettra de les rendre encore plus compltes. Actuellement, le seul bouton que vous pouvez contrler est la notification elle-mme, lorsque l'utilisateur clique dessus. Mme si c'est une pratique maintenant bien integr chez les utilisateurs, ce n'est pas le plus ergonomique. Imaginez que vous recevez un e-mail. V ous pourriez donner la possibilit l'utilisateur de le lire ou de l'archiver directement. Avec les anciennes notifications, cela n'aurait pas t possible. Dornavant, il existe la mthode public NotificationCompat.Builder addAction(int icon, CharSequence title, PendingIntent intent) que vous appelez sur votre NotificationCompat.Builder. Les paramtres correspondent : icon est l'icne qui s'affichera gauche de votre bouton. title est le texte qui s'affichera droite de votre bouton. intent est l'intent qui sera lanc lorsque vous cliquerez sur le bouton, c'est bien entendu un PendingIntent. V ous tes cens savoir comment crer des PendingIntent, je passerai donc par l'intermdiaire d'une mthode private PendingIntent getPendingIntent() qui s'occupera de lancer un intent sur l'activit courante dans laquelle je me trouve. Cependant, vous pourrez retrouver son implmentation sur le projet GitHub du tutoriel. Si nous devons complter le builder du style de la grande image de notre exemple prcedent, nous aurons quelque chose semblable ceci en rajoutant deux boutons d'action : Code : Java builder.setContentTitle(getResources().getText(R.string.big_pic_title)) .setSmallIcon(R.drawable.ic_launcher) .addAction(android.R.drawable.ic_menu_camera, getResources().getText(R.string.notification_action_2), getPendingIntent()) .addAction(android.R.drawable.ic_menu_send, getResources().getText(R.string.notification_action_1), getPendingIntent()).setWhen(System.currentTimeMillis());

Cela nous donnera le beau rsultat suivant :

www.siteduzero.com

Partie 2 : Des nouveaux composants

70/79

Excution de la notification affichant une

grande image et deux boutons

www.siteduzero.com

Partie 2 : Des nouveaux composants

71/79

Le partage par NFC


Malgr ce qu'un grand nombre d'utilisateurs penseraient, la technologie NFC (Nier Field Communication, ou en franais Communication en Champ Proche) n'est pas neuve. Depuis quelques annes seulement, on en entend parler de plus en plus. Notamment grce aux smartphones qui dmocratisent grande vitesse cette technologie. Elle vous permettra d'changer des donnes une frquence faible et courte distance (moins de 10cm). Nous n'allons pas rentrer dans les dtails techniques de cette technologie dans ce chapitre. Android a prvu une API pour nous permettre de rester, plus ou moins, un haut niveau d'abstraction. Cependant, il vous faudra peut-tre relire deux fois certaines explications puisque nous allons devoir directement jouer avec des bits sur certains points.

Les diffrents tags existants Identification des diffrents tags


Avant de vous lancez dans l'apprentissage du NFC, il serait sans doute utile de savoir si votre appareil dans votre poche le possde. Pour ce faire, vous devrez le vrifier dans la catgorie Sans fil et rseaux des paramtres de votre smartphone. A partir de l, vous pouvez activer votre NFC et Android Beam. Ce dernier sera galement vu en dernire partie de ce chapitre. V ous pouvez ds maintenant l'activer en prvision de la suite. A partir de maintenant, votre smartphone sera constamment la recherche d'un tag NFC, mme lorsque vous serez sur l'cran de verrouillage. Une fois que votre appareil captera un tag NFC, il tentera de le traiter le mieux possible. Il encapsulera le tag dans un intent regroupant toutes les informations ncessaires et l'enverra au systme qui cherchera une activit parmi l'une de vos applications qui filtre le type de tag qui a t identifi. V ous devez donc savoir qu'il existe plusieurs sortes de tag tant donn que cette technologie n'a pas t standardise ds sa sortie (et qu'elle ne l'est pas encore tout fait). Nous pouvons donc filtrer sur 3 niveaux de priorits : ACTION_NDEF_DISCOVERED est le plus grand niveau de proprit dans tout le systme. Le systme d'identification des tags tentera de lancer une activit avec cet intent plutt que d'autres intents en attente dans votre systme. Si le systme ne trouve aucune activit qui gre cet intent, il passera au type suivant. ACTION_TECH_DISCOVERED est un niveau de proprit juste en dessous du prcdent. Il sera lanc si le message du tag n'est pas formatt par le standard NDEF. ACTION_TAG_DISCOVERED est l'intent qui sera lanc si aucune autre activit n'a t trouv dans le systme pour grer le tag dcouvert. Les messages NDEF sont la tentative de standardisations des forums NFC qui est un consortium international cr pour promouvoir la technologie NFC. Le problme c'est que cette standardisation n'est pas suivie par tout le monde. Chose pour laquelle Android possde 3 types diffrents de tag NFC pour couvrir un large nombre de tag.

Systme d'identification du tag

Structure d'un message NDEF


Avant d'aller plus loin, il est utile de savoir comment est structurer un message NDEF. V oici un petit schma qui l'explique assez

www.siteduzero.com

Partie 2 : Des nouveaux composants


simplement :

72/79

Structure d'un message NDEF

Qu'avons-nous l ? Tout simplement un message qui comporte un tableau de record, d'enregistrement, avec un header (comportant des informations comme son identifiant et autres et un payload qui est la donne en elle-mme). Chaque record possde un espace mmoire assez rduit. Il faut donc penser les rpartir sur plusieurs records si nous implmentons une application qui crit des NDEF messages sur des tags ou bien rcuprer chaque record si nous implmentons un lecteur. Chose que nous allons faire dans la suite de ce chapitre.

Implmentation dans notre application


Comment concrtiser ce filtre dans notre application ? C'est trs simple, tout se passe dans notre fichier manifest. Nous allons spcifier plusieurs petite chose dans le noeud <manifest>: La version minimum du SDK que doit spcifier votre application pour accder l'entiret de l'API NFC. La permission du NFC pour signaler l'utilisateur que nous utiliserons cette fonctionnalit et pour permettre au Play Store de filtrer les terminaux compatibles. Si le NFC doit tre activ ou non lors de l'excution de notre application. Au niveau du noeud racine , nous rajouterons : Code : XML <uses-sdk android:minSdkVersion="10"/> <uses-permission android:name="android.permission.NFC" /> <uses-feature android:name="android.hardware.nfc" android:required="boolean" />

Maintenant, pour les activits qui seront destines grer le NFC, nous devrons ajouter un noeud <intent-filter> avec un lment <action> qui indiquera le type de tag que nous traitons et la catgorie du filtre avec un lment <category>. Nous aurons donc quelque chose comme ceci : Code : XML <intent-filter> <action android:name="android.nfc.action.NDEF_DISCOVERED" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter>

Avec ce filtre, le systme sera que nous traitons les tags NDEF et pourra proposer notre activit lorsqu'il captera un tag de ce type.

Lecture d'un tag Activit destin grer la lecture du tag


Bien, on va enfin commencer s'amuser ! Cependant, nous allons nous limiter aux messages NDEF pour tenter de supporter cette standardisation que Google et d'autres acteurs comme SONY ou Philips tentent de rpandre. De plus, il est bien plus simple d'utiliser les messages NDEF pour apprendre puisque Android offre une API spcialement prvue pour ce type de messages. Pour ce faire, nous n'aurons pas besoin de grand chose. Dans une activit quelconque, nous lui attacherons un fichier XML

www.siteduzero.com

Partie 2 : Des nouveaux composants

73/79

d'affichage pour afficher simplement un texte qui sera modifier par le texte que nous enverrons par un tag (ou par une mthode explique plus loin pour simuler un tag). Quant notre activit, nous nous contenterons de dsrialiser ce fichier XML et de jouer avec l'adaptateur NFC, NfcAdapter. Son initialisation se fait avec la mthode public static NfcAdapter getDefaultAdapter(Context context) qui est une mthode statique pouvant tre appel partir de la classe prcdemment cite. Ds que c'est chose faite, nous devons vrifier que l'appareil qui tente de lancer l'activit a bien le NFC ou s'il est bien activ. Pensez qu'il est toujours possible pour un utilisateur de tlcharger une application qui ne lui est pas destine initialement. Il pourrait donc installer une application qui ne figure pas sur son Play Store parce que ses appareils enregistrs ne sont pas compatibles. Nous vrifierons que notre adaptateur est bien diffrent de null ou s'il est bien activ par la mthode public boolean isEnabled(). Notre mthode public void onCreate(Bundle savedInstanceState) ressemblera donc quelque chose comme le code ci-dessous. Code : Java @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_nfc); this.mTextView = (TextView) findViewById(R.id.textView1); this.mNfcAdapter = NfcAdapter.getDefaultAdapter(this); if (mNfcAdapter == null || !mNfcAdapter.isEnabled()) { Toast.makeText(this, R.string.text_no_nfc, Toast.LENGTH_SHORT).show(); finish(); return; } }

Maintenant, pour que notre activit puisse grer la dcouverte d'un TAG au premier plan, il est ncessaire de redfinir la mthode protected void onResume() et la mthode protected void onPause(). Dans la premire mthode, nous activerons la possibilit d'identifier le tag pass dans un Intent via la mthode public void enableForegroundDispatch(Activity activity, PendingIntent intent, IntentFilter[] filters, String[][] techLists). A quoi correspondent tous ces paramtres ? Le paramtre Activity est bien entendu destin renseigner l'activit sur lequel vous vous trouvez. Le paramtre PendingIntent renseigne un intent excuter plus tard pour indiquer l'activit qui se charge du traitement du tag. Le paramtre IntentFilter[] pour affiner le traitement des messages, mettre null si vous acceptez tout. Le paramtre String[][] est renseign pour excuter un matching de traitement avec le type de tag de priorit infrieur, mettre null si vous ne voulez rien matcher. Quant la seconde mthode, nous devons dsactiver cette possibilit de traitement des tags sur l'activit au premier plan par la mthode public void disableForegroundDispatch(Activity activity) en renseignant simplement l'activit courante. V ous aurez donc une implmentation similaire au code suivant : Code : Java @Override protected void onResume() { super.onResume(); Intent intent = new Intent(this, this.getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP); PendingIntent pIntent = PendingIntent.getActivity(this, 0, intent, 0); IntentFilter[] filters = null; String[][] techListArray = null; mNfcAdapter.enableForegroundDispatch(this, pIntent, filters, techListArray); } @Override

www.siteduzero.com

Partie 2 : Des nouveaux composants


protected void onPause() { super.onPause(); mNfcAdapter.disableForegroundDispatch(this); }

74/79

Pour finir, nous allons voir comment traiter notre intent qui comporte notre NDEF message. Nous allons donc crer une mthode avec la signature private void resolveIntent(Intent intent) qui rcuprera un tableau de Parcelable correspondant aux donnes extensions placs par le tag, et ce via la mthode public Parcelable[] getParcelableArrayExtra(String name) en lui passant en paramtre la constante NfcAdapter.EXTRA_NDEF_MESSAGES. A partir de l, nous pourrons recopier son contenu dans un tableau du type NdefMessage et traiter les donnes comme bon nous semble. Si nous prenons un exemple simple o il existe simplement des donnes dans le premier enregistrement du message NDEF, on aura une mthode similaire : Code : Java private void resolveIntent(Intent intent) { String action = intent.getAction(); if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(action)) { Parcelable[] rawMsgs = intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES); if (rawMsgs != null) { NdefMessage[] messages = new NdefMessage[rawMsgs.length]; for (int i = 0; i < rawMsgs.length; i++) { messages[i] = (NdefMessage) rawMsgs[i]; } // Exemple basique de rcupration des donnes dans le tableau String str = new String(messages[0].getRecords()[0].getPayload()); mTextView.setText(str); } } }

Il vous suffit alors d'appeler cette mthode la fin de la mthode public void onCreate(Bundle savedInstanceState) de votre activit pour grer l'intent que vous recevrez dans votre activit lorsque votre systme captera un tag NDEF. V otre application est maintenant capable d'intercepter les messages NDEF dcouvert par votre systme et proposera donc votre activit pour les lire.

Un mulateur de tag NDEF


C'est bien beau tout a mais comment pouvons-nous tester notre application si nous ne disposons pas de tag NFC comportant des NDEF messages ? C'est trs simple. Pour ce faire, nous aurons besoin de 2 mthodes assez gnrique que vous n'aurez pas forcment besoin de comprende (c'est un peu technique puisque c'est de la manipulation de bits) et d'une autre activit (c'est important sinon a ne fonctionnera pas). Nous aurons donc besoin des deux mthodes suivantes permettant la cration d'un message NDEF et de ses records : Code : Java public static NdefMessage createMessage(String text, boolean encode) { NdefRecord[] records = new NdefRecord[1]; records[0] = createRecord(text, Locale.FRENCH, encode); return new NdefMessage(records); } public static NdefRecord createRecord(String text, Locale locale, boolean encode) { byte[] langBytes = locale.getLanguage().getBytes( Charset.forName("US-ASCII")); Charset utfEncoding = encode ? Charset.forName("UTF-8") : Charset

www.siteduzero.com

Partie 2 : Des nouveaux composants


.forName("UTF-16"); byte[] textBytes = text.getBytes(utfEncoding); int utfBit = encode ? 0 : (1 << 7); char status = (char) (utfBit + langBytes.length); byte[] data = new byte[langBytes.length + textBytes.length + 1]; data[0] = (byte) status; System.arraycopy(langBytes, 0, data, 1, langBytes.length); System.arraycopy(textBytes, 0, data, 1 + langBytes.length, textBytes.length); return new NdefRecord(NdefRecord.TNF_WELL_KNOWN, NdefRecord.RTD_TEXT, new byte[0], data); }

75/79

Pour des soucis de facilit, j'ai plac ces mthodes en static dans une classe utilitaire NFCUtils.

Dans notre activit, nous utiliserons la mthode public static NdefMessage createMessage(String text, boolean encode) que nous appellerons lorsqu'un utilisera cliquera sur un bouton pour lancer un intent test comportant un message que nous avons dfini de la manire suivante : Code : Java public void sendTag(View v) { Intent i = new Intent(NfcAdapter.ACTION_NDEF_DISCOVERED); NdefMessage[] messages = new NdefMessage[1]; messages[0] = NFCUtils.createMessage("Simule message NDEF", true); i.putExtra(NfcAdapter.EXTRA_NDEF_MESSAGES, messages); startActivity(i); }

Ainsi, lorsque nous cliquerons sur le bouton, notre systme nous proposera notre premire activit qui offre la possibilit de grer des NDEF messages.

www.siteduzero.com

Partie 2 : Des nouveaux composants

76/79

Excution de l'mulateur de messages

NDEF

Echange par Beam


Nous abordons maintenant la dernire partie de ce chapitre avec une utilisation du NFC trs intressante. V ous connaissez tous les connectivits comme le Bluetooth ou le WiFi qui vous permettent d'changer des donnes entre deux terminaux. Le problme, c'est que ce ne sont pas les technologies les plus rapides et les plus facile utiliser pour transfrer de l'information. C'est l que le NFC arrive pour palier avec une facilit dconcertante. L'ide est de lancer le partage juste en rapprochant deux smartphones dos dos, rien de plus. Cependant, pour les dveloppeurs, c'est une chose de plus implmenter. Cette fois-ci, cela va tre un peu diffrent que le lecteur de tag que nous avons dvelopp. Nous allons devoir ici tre rcepteur et envoyeur. V ous tes cens pouvoir recevoir de l'information et en envoyer. Pour ce faire, Android offre une API lgrement diffrente pour que cela soit plus simple pour les dveloppeurs d'envoyer des donnes.

www.siteduzero.com

Partie 2 : Des nouveaux composants

77/79

Commenons par implmenter une interface dans notre activit, CreateNdefMessageCallback. Comme vous pouvez le deviner, cette interface servira implmenter les mthodes pour crer les messages NDEF lorsque nous envoyons des donnes un autre terminal.Nous implmentons donc la mthode public NdefMessage createNdefMessage(NfcEvent event) de faon trs similaire notre mulateur, quelques exceptions prs. Nous aurons besoin de la mthode suivante pour crer un mime : Code : Java public static NdefRecord createMimeRecord(String mimeType, byte[] payload) { byte[] mimeBytes = mimeType.getBytes(Charset.forName("US-ASCII")); NdefRecord mimeRecord = new NdefRecord(NdefRecord.TNF_MIME_MEDIA, mimeBytes, new byte[0], payload); return mimeRecord; }

Le mime nous permettra d'indiquer le chemin vers le paquetage contenant l'activit qui permettra de traiter le transfert Beam. Nous devrons donc initialiser un tableau de record qui comporte l'enregistrement mime et le payload reprsentant la donne transfrer. Empaqueter le tout dans un NdefMessage pour ensuite le retourner dans la mthode. Nous obtenons donc simplement le code suivant : Code : Java @Override public NdefMessage createNdefMessage(NfcEvent event) { String text = "Message share by Beam !"; NdefRecord[] records = new NdefRecord[] { NFCUtils.createMimeRecord( "application/com.siteduzero.android.nfc", text.getBytes()) }; NdefMessage msg = new NdefMessage(records); return msg; }

Maintenant, pour rendre actif l'appel cette mthode, nous allons appeler, dans la mthode protected void onCreate(Bundle savedInstanceState), la mthode public void setNdefPushMessageCallback (NfcAdapter.CreateNdefMessageCallback callback, Activity activity, Activity... activities) sur l'adaptateur NFC que nous avons initialis juste avant. Nous lui donnons donc l'instance du callback en paramtre et l'activit courante dans laquelle il se trouve pour rendre oprationnel notre code. La rception des messages se fait exactement de la mme faon que prcdent sauf qu'il vous faudra redfinir une mthode supplmentaire public void onNewIntent(Intent intent) pour appeler la mthode private void resolveIntent(Intent intent) dveloppe dans la sous partie prcdente de ce chapitre. A partir de l, si vous excutez votre code et que vous mettez dos dos deux terminaux avec la technologie Beam, vous arrivez au resultat suivant :

www.siteduzero.com

Partie 2 : Des nouveaux composants

78/79

Excution du programme Android Beam

Bien entendu, ce tutoriel est trs loin d'tre termin. V ous pourrez retrouver ce mme tutoriel en bta via ce lien. N'hsitez pas me donner votre avis pour faire voluer ce tutoriel. Il a pour but d'tre le plus communautaire possible. Je suis donc ouvert toutes vos critiques, questions et remarques constructives !

Remerciements
Aux lecteurs et bta-testeurs qui me font des critiques constructives sur le contenu de mon tutoriel. Fumble pour la validation de mon tutoriel. Bluekicks pour l'icne de mon tutoriel.

www.siteduzero.com

Vous aimerez peut-être aussi